Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a2a0610de | ||
|
|
19e7a92fb7 | ||
|
|
57c13a208e | ||
|
|
96eeffb587 | ||
|
|
3cbd01f6ec | ||
|
|
9ed02459c1 | ||
|
|
b26ec4af93 | ||
|
|
ae78112205 | ||
|
|
4ba3d8e7d6 | ||
|
|
d9bc5a5e5d | ||
|
|
fedafc47b0 | ||
|
|
0237938b3b | ||
|
|
6caa75344d | ||
|
|
e51fb2f917 |
No files matched your search
@@ -16,7 +16,6 @@ local command =
|
|||||||
}.join(" ")
|
}.join(" ")
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
catalog.`actions/checkout@v6`
|
|
||||||
new {
|
new {
|
||||||
name = "gradle build java executables"
|
name = "gradle build java executables"
|
||||||
shell = "bash"
|
shell = "bash"
|
||||||
|
|||||||
Generated
-3
@@ -185,9 +185,6 @@ jobs:
|
|||||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
- name: gradle build java executables
|
- name: gradle build java executables
|
||||||
shell: bash
|
shell: bash
|
||||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:build pkl-cli:build pkl-codegen-java:build pkl-codegen-kotlin:build
|
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:build pkl-cli:build pkl-codegen-java:build pkl-codegen-kotlin:build
|
||||||
|
|||||||
Generated
-3
@@ -183,9 +183,6 @@ jobs:
|
|||||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
- name: gradle build java executables
|
- name: gradle build java executables
|
||||||
shell: bash
|
shell: bash
|
||||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:build pkl-cli:build pkl-codegen-java:build pkl-codegen-kotlin:build
|
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:build pkl-cli:build pkl-codegen-java:build pkl-codegen-kotlin:build
|
||||||
|
|||||||
Generated
-3
@@ -183,9 +183,6 @@ jobs:
|
|||||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
- name: gradle build java executables
|
- name: gradle build java executables
|
||||||
shell: bash
|
shell: bash
|
||||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:build pkl-cli:build pkl-codegen-java:build pkl-codegen-kotlin:build
|
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true pkl-doc:build pkl-cli:build pkl-codegen-java:build pkl-codegen-kotlin:build
|
||||||
|
|||||||
Generated
-3
@@ -184,9 +184,6 @@ jobs:
|
|||||||
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
if [[ "$RUNNER_DEBUG" -eq 1 ]]; then
|
||||||
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
echo "DEBUG_ARGS=--info --stacktrace" >> $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
- name: gradle build java executables
|
- name: gradle build java executables
|
||||||
shell: bash
|
shell: bash
|
||||||
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:build pkl-cli:build pkl-codegen-java:build pkl-codegen-kotlin:build
|
run: ./gradlew $DEBUG_ARGS --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:build pkl-cli:build pkl-codegen-java:build pkl-codegen-kotlin:build
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ plugins {
|
|||||||
id("me.champeau.jmh")
|
id("me.champeau.jmh")
|
||||||
}
|
}
|
||||||
|
|
||||||
val truffle: Configuration by configurations.creating
|
val truffle: Configuration = configurations.create("truffle")
|
||||||
val graal: Configuration by configurations.creating
|
val graal: Configuration = configurations.create("graal")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
jmh(projects.pklCore)
|
jmh(projects.pklCore)
|
||||||
|
|||||||
@@ -63,58 +63,60 @@ fun Project.configurePklPomMetadata() {
|
|||||||
|
|
||||||
/** Configures POM validation task to check for unresolved versions and snapshots in releases. */
|
/** Configures POM validation task to check for unresolved versions and snapshots in releases. */
|
||||||
fun Project.configurePomValidation() {
|
fun Project.configurePomValidation() {
|
||||||
val validatePom by tasks.registering {
|
val validatePom =
|
||||||
if (tasks.findByName("generatePomFileForLibraryPublication") == null) {
|
tasks.register("validatePom") {
|
||||||
return@registering
|
if (tasks.findByName("generatePomFileForLibraryPublication") == null) {
|
||||||
}
|
return@register
|
||||||
val generatePomFileForLibraryPublication by tasks.existing(GenerateMavenPom::class)
|
}
|
||||||
val outputFile =
|
val generatePomFileForLibraryPublication =
|
||||||
layout.buildDirectory.file("validatePom") // dummy output to satisfy up-to-date check
|
tasks.named<GenerateMavenPom>("generatePomFileForLibraryPublication")
|
||||||
|
val outputFile =
|
||||||
|
layout.buildDirectory.file("validatePom") // dummy output to satisfy up-to-date check
|
||||||
|
|
||||||
dependsOn(generatePomFileForLibraryPublication)
|
dependsOn(generatePomFileForLibraryPublication)
|
||||||
inputs.file(generatePomFileForLibraryPublication.get().destination)
|
inputs.file(generatePomFileForLibraryPublication.get().destination)
|
||||||
outputs.file(outputFile)
|
outputs.file(outputFile)
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
outputFile.get().asFile.delete()
|
outputFile.get().asFile.delete()
|
||||||
|
|
||||||
val pomFile = generatePomFileForLibraryPublication.get().destination
|
val pomFile = generatePomFileForLibraryPublication.get().destination
|
||||||
assert(pomFile.exists())
|
assert(pomFile.exists())
|
||||||
|
|
||||||
val text = pomFile.readText()
|
val text = pomFile.readText()
|
||||||
|
|
||||||
run {
|
run {
|
||||||
val unresolvedVersion = Regex("<version>.*[+,()\\[\\]].*</version>")
|
val unresolvedVersion = Regex("<version>.*[+,()\\[\\]].*</version>")
|
||||||
val matches = unresolvedVersion.findAll(text).toList()
|
val matches = unresolvedVersion.findAll(text).toList()
|
||||||
if (matches.isNotEmpty()) {
|
if (matches.isNotEmpty()) {
|
||||||
throw org.gradle.api.GradleException(
|
throw org.gradle.api.GradleException(
|
||||||
"""
|
"""
|
||||||
Found unresolved version selector(s) in generated POM:
|
Found unresolved version selector(s) in generated POM:
|
||||||
${matches.joinToString("\n") { it.groupValues[0] }}
|
${matches.joinToString("\n") { it.groupValues[0] }}
|
||||||
"""
|
"""
|
||||||
.trimIndent()
|
.trimIndent()
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||||
if (buildInfo.isReleaseBuild) {
|
if (buildInfo.isReleaseBuild) {
|
||||||
val snapshotVersion = Regex("<version>.*-SNAPSHOT</version>")
|
val snapshotVersion = Regex("<version>.*-SNAPSHOT</version>")
|
||||||
val matches = snapshotVersion.findAll(text).toList()
|
val matches = snapshotVersion.findAll(text).toList()
|
||||||
if (matches.isNotEmpty()) {
|
if (matches.isNotEmpty()) {
|
||||||
throw org.gradle.api.GradleException(
|
throw org.gradle.api.GradleException(
|
||||||
"""
|
"""
|
||||||
Found snapshot version(s) in generated POM of Pkl release version:
|
Found snapshot version(s) in generated POM of Pkl release version:
|
||||||
${matches.joinToString("\n") { it.groupValues[0] }}
|
${matches.joinToString("\n") { it.groupValues[0] }}
|
||||||
"""
|
"""
|
||||||
.trimIndent()
|
.trimIndent()
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
outputFile.get().asFile.writeText("OK")
|
outputFile.get().asFile.writeText("OK")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
tasks.named("publish") { dependsOn(validatePom) }
|
tasks.named("publish") { dependsOn(validatePom) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ plugins.withType(MavenPublishPlugin::class).configureEach {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val allDependencies by tasks.registering(DependencyReportTask::class)
|
val allDependencies = tasks.register<DependencyReportTask>("allDependencies")
|
||||||
|
|
||||||
tasks.withType(Test::class).configureEach {
|
tasks.withType(Test::class).configureEach {
|
||||||
System.getProperty("testReportsDir")?.let { reportsDir ->
|
System.getProperty("testReportsDir")?.let { reportsDir ->
|
||||||
|
|||||||
@@ -132,8 +132,8 @@ tasks.shadowJar {
|
|||||||
|
|
||||||
shadow { addShadowVariantIntoJavaComponent = false }
|
shadow { addShadowVariantIntoJavaComponent = false }
|
||||||
|
|
||||||
val testFatJar by
|
val testFatJar =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testFatJar") {
|
||||||
testClassesDirs = files(tasks.test.get().testClassesDirs)
|
testClassesDirs = files(tasks.test.get().testClassesDirs)
|
||||||
classpath =
|
classpath =
|
||||||
// compiled test classes
|
// compiled test classes
|
||||||
@@ -148,47 +148,48 @@ val testFatJar by
|
|||||||
|
|
||||||
tasks.check { dependsOn(testFatJar) }
|
tasks.check { dependsOn(testFatJar) }
|
||||||
|
|
||||||
val validateFatJar by tasks.registering {
|
val validateFatJar =
|
||||||
val outputFile = layout.buildDirectory.file("validateFatJar/result.txt")
|
tasks.register("validateFatJar") {
|
||||||
inputs.files(tasks.shadowJar)
|
val outputFile = layout.buildDirectory.file("validateFatJar/result.txt")
|
||||||
inputs.property("nonRelocations", nonRelocations)
|
inputs.files(tasks.shadowJar)
|
||||||
outputs.file(outputFile)
|
inputs.property("nonRelocations", nonRelocations)
|
||||||
|
outputs.file(outputFile)
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
val unshadowedFiles = mutableListOf<String>()
|
val unshadowedFiles = mutableListOf<String>()
|
||||||
zipTree(tasks.shadowJar.get().outputs.files.singleFile).visit {
|
zipTree(tasks.shadowJar.get().outputs.files.singleFile).visit {
|
||||||
val fileDetails = this
|
val fileDetails = this
|
||||||
val path = fileDetails.relativePath.pathString
|
val path = fileDetails.relativePath.pathString
|
||||||
if (
|
if (
|
||||||
!(fileDetails.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) })
|
||||||
) {
|
) {
|
||||||
// don't throw exception inside `visit`
|
// don't throw exception inside `visit`
|
||||||
// as this gives a misleading "Could not expand ZIP" error message
|
// as this gives a misleading "Could not expand ZIP" error message
|
||||||
unshadowedFiles.add(path)
|
unshadowedFiles.add(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (unshadowedFiles.isEmpty()) {
|
||||||
|
outputFile.get().asFile.writeText("SUCCESS")
|
||||||
|
} else {
|
||||||
|
outputFile.get().asFile.writeText("FAILURE")
|
||||||
|
throw GradleException("Found unshadowed files:\n" + unshadowedFiles.joinToString("\n"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unshadowedFiles.isEmpty()) {
|
|
||||||
outputFile.get().asFile.writeText("SUCCESS")
|
|
||||||
} else {
|
|
||||||
outputFile.get().asFile.writeText("FAILURE")
|
|
||||||
throw GradleException("Found unshadowed files:\n" + unshadowedFiles.joinToString("\n"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
tasks.check { dependsOn(validateFatJar) }
|
tasks.check { dependsOn(validateFatJar) }
|
||||||
|
|
||||||
val resolveSourcesJars by
|
val resolveSourcesJars =
|
||||||
tasks.registering(ResolveSourcesJars::class) {
|
tasks.register<ResolveSourcesJars>("resolveSourcesJars") {
|
||||||
configuration.set(configurations.runtimeClasspath)
|
configuration.set(configurations.runtimeClasspath)
|
||||||
outputDir.set(layout.buildDirectory.dir("resolveSourcesJars"))
|
outputDir.set(layout.buildDirectory.dir("resolveSourcesJars"))
|
||||||
}
|
}
|
||||||
|
|
||||||
val fatSourcesJar by
|
val fatSourcesJar =
|
||||||
tasks.registering(MergeSourcesJars::class) {
|
tasks.register<MergeSourcesJars>("fatSourcesJar") {
|
||||||
plugins.withId("pklJavaLibrary") { inputJars.from(tasks.named("sourcesJar")) }
|
plugins.withId("pklJavaLibrary") { inputJars.from(tasks.named("sourcesJar")) }
|
||||||
inputJars.from(firstPartySourcesJarsConfiguration)
|
inputJars.from(firstPartySourcesJarsConfiguration)
|
||||||
inputJars.from(resolveSourcesJars.map { fileTree(it.outputDir) })
|
inputJars.from(resolveSourcesJars.map { fileTree(it.outputDir) })
|
||||||
@@ -213,7 +214,7 @@ publishing {
|
|||||||
artifact(fatSourcesJar.flatMap { it.outputJar.asFile }) { classifier = "sources" }
|
artifact(fatSourcesJar.flatMap { it.outputJar.asFile }) { classifier = "sources" }
|
||||||
|
|
||||||
plugins.withId("pklJavaLibrary") {
|
plugins.withId("pklJavaLibrary") {
|
||||||
val javadocJar by tasks.existing(Jar::class)
|
val javadocJar = tasks.named<Jar>("javadocJar")
|
||||||
// Javadoc Jar is not fat (didn't invest effort)
|
// Javadoc Jar is not fat (didn't invest effort)
|
||||||
artifact(javadocJar.flatMap { it.archiveFile }) { classifier = "javadoc" }
|
artifact(javadocJar.flatMap { it.archiveFile }) { classifier = "javadoc" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,11 +21,15 @@ plugins { id("de.undercouch.download") }
|
|||||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||||
|
|
||||||
// tries to minimize chance of corruption by download-to-temp-file-and-move
|
// tries to minimize chance of corruption by download-to-temp-file-and-move
|
||||||
val downloadGraalVmAarch64 by
|
val downloadGraalVmAarch64 =
|
||||||
tasks.registering(Download::class) { configureDownloadGraalVm(buildInfo.graalVmAarch64) }
|
tasks.register<Download>("downloadGraalVmAarch64") {
|
||||||
|
configureDownloadGraalVm(buildInfo.graalVmAarch64)
|
||||||
|
}
|
||||||
|
|
||||||
val downloadGraalVmAmd64 by
|
val downloadGraalVmAmd64 =
|
||||||
tasks.registering(Download::class) { configureDownloadGraalVm(buildInfo.graalVmAmd64) }
|
tasks.register<Download>("downloadGraalVmAmd64") {
|
||||||
|
configureDownloadGraalVm(buildInfo.graalVmAmd64)
|
||||||
|
}
|
||||||
|
|
||||||
fun Download.configureDownloadGraalVm(graalvm: BuildInfo.GraalVm) {
|
fun Download.configureDownloadGraalVm(graalvm: BuildInfo.GraalVm) {
|
||||||
onlyIf { !graalvm.installDir.exists() }
|
onlyIf { !graalvm.installDir.exists() }
|
||||||
@@ -37,14 +41,14 @@ fun Download.configureDownloadGraalVm(graalvm: BuildInfo.GraalVm) {
|
|||||||
tempAndMove(true)
|
tempAndMove(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
val verifyGraalVmAarch64 by
|
val verifyGraalVmAarch64 =
|
||||||
tasks.registering(Verify::class) {
|
tasks.register<Verify>("verifyGraalVmAarch64") {
|
||||||
configureVerifyGraalVm(buildInfo.graalVmAarch64)
|
configureVerifyGraalVm(buildInfo.graalVmAarch64)
|
||||||
dependsOn(downloadGraalVmAarch64)
|
dependsOn(downloadGraalVmAarch64)
|
||||||
}
|
}
|
||||||
|
|
||||||
val verifyGraalVmAmd64 by
|
val verifyGraalVmAmd64 =
|
||||||
tasks.registering(Verify::class) {
|
tasks.register<Verify>("verifyGraalVmAmd64") {
|
||||||
configureVerifyGraalVm(buildInfo.graalVmAmd64)
|
configureVerifyGraalVm(buildInfo.graalVmAmd64)
|
||||||
dependsOn(downloadGraalVmAmd64)
|
dependsOn(downloadGraalVmAmd64)
|
||||||
}
|
}
|
||||||
@@ -60,15 +64,15 @@ fun Verify.configureVerifyGraalVm(graalvm: BuildInfo.GraalVm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val installGraalVmAarch64 by
|
val installGraalVmAarch64 =
|
||||||
tasks.registering(InstallGraalVm::class) {
|
tasks.register<InstallGraalVm>("installGraalVmAarch64") {
|
||||||
dependsOn(verifyGraalVmAarch64)
|
dependsOn(verifyGraalVmAarch64)
|
||||||
graalVm = buildInfo.graalVmAarch64
|
graalVm = buildInfo.graalVmAarch64
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val installGraalVmAmd64 by
|
val installGraalVmAmd64 =
|
||||||
tasks.registering(InstallGraalVm::class) {
|
tasks.register<InstallGraalVm>("installGraalVmAmd64") {
|
||||||
dependsOn(verifyGraalVmAmd64)
|
dependsOn(verifyGraalVmAmd64)
|
||||||
graalVm = buildInfo.graalVmAmd64
|
graalVm = buildInfo.graalVmAmd64
|
||||||
}
|
}
|
||||||
@@ -47,8 +47,8 @@ dependencies {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val validateHtml by
|
val validateHtml =
|
||||||
tasks.registering(JavaExec::class) {
|
tasks.register<JavaExec>("validateHtml") {
|
||||||
val resultFile = layout.buildDirectory.file("validateHtml/result.txt")
|
val resultFile = layout.buildDirectory.file("validateHtml/result.txt")
|
||||||
inputs.files(htmlValidator.sources)
|
inputs.files(htmlValidator.sources)
|
||||||
outputs.file(resultFile)
|
outputs.file(resultFile)
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ plugins {
|
|||||||
val executableSpec = project.extensions.create("executable", ExecutableSpec::class.java)
|
val executableSpec = project.extensions.create("executable", ExecutableSpec::class.java)
|
||||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||||
|
|
||||||
val javaExecutable by
|
val javaExecutable =
|
||||||
tasks.registering(ExecutableJar::class) {
|
tasks.register<ExecutableJar>("javaExecutable") {
|
||||||
group = "build"
|
group = "build"
|
||||||
dependsOn(tasks.jar)
|
dependsOn(tasks.jar)
|
||||||
inJar = tasks.shadowJar.flatMap { it.archiveFile }
|
inJar = tasks.shadowJar.flatMap { it.archiveFile }
|
||||||
@@ -77,7 +77,8 @@ fun Task.setupTestStartJavaExecutable(launcher: Provider<JavaLauncher>? = null)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val testStartJavaExecutable by tasks.registering { setupTestStartJavaExecutable() }
|
val testStartJavaExecutable =
|
||||||
|
tasks.register("testStartJavaExecutable") { setupTestStartJavaExecutable() }
|
||||||
|
|
||||||
// Setup `testStartJavaExecutable` tasks for multi-JDK testing.
|
// Setup `testStartJavaExecutable` tasks for multi-JDK testing.
|
||||||
val testStartJavaExecutableOnOtherJdks =
|
val testStartJavaExecutableOnOtherJdks =
|
||||||
|
|||||||
@@ -30,22 +30,26 @@ plugins {
|
|||||||
val executableSpec = project.extensions.getByType<ExecutableSpec>()
|
val executableSpec = project.extensions.getByType<ExecutableSpec>()
|
||||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||||
|
|
||||||
val stagedMacAmd64Executable: Configuration by configurations.creating
|
val stagedMacAmd64Executable: Configuration = configurations.create("stagedMacAmd64Executable")
|
||||||
val stagedMacAarch64Executable: Configuration by configurations.creating
|
val stagedMacAarch64Executable: Configuration = configurations.create("stagedMacAarch64Executable")
|
||||||
val stagedLinuxAmd64Executable: Configuration by configurations.creating
|
val stagedLinuxAmd64Executable: Configuration = configurations.create("stagedLinuxAmd64Executable")
|
||||||
val stagedLinuxAarch64Executable: Configuration by configurations.creating
|
val stagedLinuxAarch64Executable: Configuration =
|
||||||
val stagedAlpineLinuxAmd64Executable: Configuration by configurations.creating
|
configurations.create("stagedLinuxAarch64Executable")
|
||||||
val stagedWindowsAmd64Executable: Configuration by configurations.creating
|
val stagedAlpineLinuxAmd64Executable: Configuration =
|
||||||
|
configurations.create("stagedAlpineLinuxAmd64Executable")
|
||||||
|
val stagedWindowsAmd64Executable: Configuration =
|
||||||
|
configurations.create("stagedWindowsAmd64Executable")
|
||||||
|
|
||||||
val nativeImageClasspath by configurations.creating {
|
val nativeImageClasspath =
|
||||||
extendsFrom(configurations.runtimeClasspath.get())
|
configurations.create("nativeImageClasspath") {
|
||||||
// Ensure native-image version uses GraalVM C SDKs instead of Java FFI or JNA
|
extendsFrom(configurations.runtimeClasspath.get())
|
||||||
// (comes from artifact `mordant-jvm-graal-ffi`).
|
// Ensure native-image version uses GraalVM C SDKs instead of Java FFI or JNA
|
||||||
exclude("com.github.ajalt.mordant", "mordant-jvm-ffm")
|
// (comes from artifact `mordant-jvm-graal-ffi`).
|
||||||
exclude("com.github.ajalt.mordant", "mordant-jvm-ffm-jvm")
|
exclude("com.github.ajalt.mordant", "mordant-jvm-ffm")
|
||||||
exclude("com.github.ajalt.mordant", "mordant-jvm-jna")
|
exclude("com.github.ajalt.mordant", "mordant-jvm-ffm-jvm")
|
||||||
exclude("com.github.ajalt.mordant", "mordant-jvm-jna-jvm")
|
exclude("com.github.ajalt.mordant", "mordant-jvm-jna")
|
||||||
}
|
exclude("com.github.ajalt.mordant", "mordant-jvm-jna-jvm")
|
||||||
|
}
|
||||||
|
|
||||||
val libs = the<LibrariesForLibs>()
|
val libs = the<LibrariesForLibs>()
|
||||||
|
|
||||||
@@ -85,32 +89,32 @@ private fun NativeImageBuild.setClasspath() {
|
|||||||
classpath.from(nativeImageClasspath)
|
classpath.from(nativeImageClasspath)
|
||||||
}
|
}
|
||||||
|
|
||||||
val macExecutableAmd64 by
|
val macExecutableAmd64 =
|
||||||
tasks.registering(NativeImageBuild::class) {
|
tasks.register<NativeImageBuild>("macExecutableAmd64") {
|
||||||
imageName = executableSpec.name.map { "$it-macos-amd64" }
|
imageName = executableSpec.name.map { "$it-macos-amd64" }
|
||||||
mainClass = executableSpec.mainClass
|
mainClass = executableSpec.mainClass
|
||||||
amd64()
|
amd64()
|
||||||
setClasspath()
|
setClasspath()
|
||||||
}
|
}
|
||||||
|
|
||||||
val macExecutableAarch64 by
|
val macExecutableAarch64 =
|
||||||
tasks.registering(NativeImageBuild::class) {
|
tasks.register<NativeImageBuild>("macExecutableAarch64") {
|
||||||
imageName = executableSpec.name.map { "$it-macos-aarch64" }
|
imageName = executableSpec.name.map { "$it-macos-aarch64" }
|
||||||
mainClass = executableSpec.mainClass
|
mainClass = executableSpec.mainClass
|
||||||
aarch64()
|
aarch64()
|
||||||
setClasspath()
|
setClasspath()
|
||||||
}
|
}
|
||||||
|
|
||||||
val linuxExecutableAmd64 by
|
val linuxExecutableAmd64 =
|
||||||
tasks.registering(NativeImageBuild::class) {
|
tasks.register<NativeImageBuild>("linuxExecutableAmd64") {
|
||||||
imageName = executableSpec.name.map { "$it-linux-amd64" }
|
imageName = executableSpec.name.map { "$it-linux-amd64" }
|
||||||
mainClass = executableSpec.mainClass
|
mainClass = executableSpec.mainClass
|
||||||
amd64()
|
amd64()
|
||||||
setClasspath()
|
setClasspath()
|
||||||
}
|
}
|
||||||
|
|
||||||
val linuxExecutableAarch64 by
|
val linuxExecutableAarch64 =
|
||||||
tasks.registering(NativeImageBuild::class) {
|
tasks.register<NativeImageBuild>("linuxExecutableAarch64") {
|
||||||
imageName = executableSpec.name.map { "$it-linux-aarch64" }
|
imageName = executableSpec.name.map { "$it-linux-aarch64" }
|
||||||
mainClass = executableSpec.mainClass
|
mainClass = executableSpec.mainClass
|
||||||
aarch64()
|
aarch64()
|
||||||
@@ -120,8 +124,8 @@ val linuxExecutableAarch64 by
|
|||||||
extraNativeImageArgs.add("-H:PageSize=65536")
|
extraNativeImageArgs.add("-H:PageSize=65536")
|
||||||
}
|
}
|
||||||
|
|
||||||
val alpineExecutableAmd64 by
|
val alpineExecutableAmd64 =
|
||||||
tasks.registering(NativeImageBuild::class) {
|
tasks.register<NativeImageBuild>("alpineExecutableAmd64") {
|
||||||
imageName = executableSpec.name.map { "$it-alpine-linux-amd64" }
|
imageName = executableSpec.name.map { "$it-alpine-linux-amd64" }
|
||||||
mainClass = executableSpec.mainClass
|
mainClass = executableSpec.mainClass
|
||||||
amd64()
|
amd64()
|
||||||
@@ -129,73 +133,75 @@ val alpineExecutableAmd64 by
|
|||||||
extraNativeImageArgs.addAll(listOf("--static", "--libc=musl"))
|
extraNativeImageArgs.addAll(listOf("--static", "--libc=musl"))
|
||||||
}
|
}
|
||||||
|
|
||||||
val windowsExecutableAmd64 by
|
val windowsExecutableAmd64 =
|
||||||
tasks.registering(NativeImageBuild::class) {
|
tasks.register<NativeImageBuild>("windowsExecutableAmd64") {
|
||||||
imageName = executableSpec.name.map { "$it-windows-amd64" }
|
imageName = executableSpec.name.map { "$it-windows-amd64" }
|
||||||
mainClass = executableSpec.mainClass
|
mainClass = executableSpec.mainClass
|
||||||
amd64()
|
amd64()
|
||||||
setClasspath()
|
setClasspath()
|
||||||
}
|
}
|
||||||
|
|
||||||
val assembleNative by tasks.existing
|
val assembleNative = tasks.named("assembleNative")
|
||||||
|
|
||||||
val testStartNativeExecutable by tasks.registering {
|
val testStartNativeExecutable =
|
||||||
dependsOn(assembleNative)
|
tasks.register("testStartNativeExecutable") {
|
||||||
|
dependsOn(assembleNative)
|
||||||
|
|
||||||
// dummy file for up-to-date checking
|
// dummy file for up-to-date checking
|
||||||
val outputFile = project.layout.buildDirectory.file("testStartNativeExecutable/output.txt")
|
val outputFile = project.layout.buildDirectory.file("testStartNativeExecutable/output.txt")
|
||||||
outputs.file(outputFile)
|
outputs.file(outputFile)
|
||||||
|
|
||||||
val execOutput = providers.exec {
|
val execOutput = providers.exec {
|
||||||
commandLine(assembleNative.get().outputs.files.singleFile, "--version")
|
commandLine(assembleNative.get().outputs.files.singleFile, "--version")
|
||||||
}
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
val outputText = execOutput.standardOutput.asText.get()
|
|
||||||
if (!outputText.contains(buildInfo.pklVersionNonUnique)) {
|
|
||||||
throw GradleException(
|
|
||||||
"Expected version output to contain current version (${buildInfo.pklVersionNonUnique}), but got '$outputText'"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
outputFile.get().asFile.toPath().apply {
|
|
||||||
try {
|
doLast {
|
||||||
parent.createDirectories()
|
val outputText = execOutput.standardOutput.asText.get()
|
||||||
} catch (_: java.nio.file.FileAlreadyExistsException) {}
|
if (!outputText.contains(buildInfo.pklVersionNonUnique)) {
|
||||||
writeText("OK")
|
throw GradleException(
|
||||||
|
"Expected version output to contain current version (${buildInfo.pklVersionNonUnique}), but got '$outputText'"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
outputFile.get().asFile.toPath().apply {
|
||||||
|
try {
|
||||||
|
parent.createDirectories()
|
||||||
|
} catch (_: java.nio.file.FileAlreadyExistsException) {}
|
||||||
|
writeText("OK")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val requiredGlibcVersion: Version = Version.parse("2.17")
|
val requiredGlibcVersion: Version = Version.parse("2.17")
|
||||||
|
|
||||||
val checkGlibc by tasks.registering {
|
val checkGlibc =
|
||||||
enabled = buildInfo.os.isLinux && !buildInfo.musl
|
tasks.register("checkGlibc") {
|
||||||
dependsOn(assembleNative)
|
enabled = buildInfo.os.isLinux && !buildInfo.musl
|
||||||
doLast {
|
dependsOn(assembleNative)
|
||||||
val exec = providers.exec {
|
doLast {
|
||||||
commandLine("objdump", "-T", assembleNative.get().outputs.files.singleFile)
|
val exec = providers.exec {
|
||||||
}
|
commandLine("objdump", "-T", assembleNative.get().outputs.files.singleFile)
|
||||||
val output = exec.standardOutput.asText.get()
|
}
|
||||||
val minimumGlibcVersion =
|
val output = exec.standardOutput.asText.get()
|
||||||
output
|
val minimumGlibcVersion =
|
||||||
.split("\n")
|
output
|
||||||
.mapNotNull { line ->
|
.split("\n")
|
||||||
val match = Regex("GLIBC_([.0-9]*)").find(line)
|
.mapNotNull { line ->
|
||||||
match?.groups[1]?.let { Version.parse(it.value) }
|
val match = Regex("GLIBC_([.0-9]*)").find(line)
|
||||||
}
|
match?.groups[1]?.let { Version.parse(it.value) }
|
||||||
.maxOrNull()
|
}
|
||||||
if (minimumGlibcVersion == null) {
|
.maxOrNull()
|
||||||
throw GradleException(
|
if (minimumGlibcVersion == null) {
|
||||||
"Could not determine glibc version from executable. objdump output: $output"
|
throw GradleException(
|
||||||
)
|
"Could not determine glibc version from executable. objdump output: $output"
|
||||||
}
|
)
|
||||||
if (minimumGlibcVersion > requiredGlibcVersion) {
|
}
|
||||||
throw GradleException(
|
if (minimumGlibcVersion > requiredGlibcVersion) {
|
||||||
"Incorrect glibc version. Found: $minimumGlibcVersion, required: $requiredGlibcVersion"
|
throw GradleException(
|
||||||
)
|
"Incorrect glibc version. Found: $minimumGlibcVersion, required: $requiredGlibcVersion"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Expose underlying task's outputs
|
// Expose underlying task's outputs
|
||||||
private fun <T : Task> Task.wraps(other: TaskProvider<T>) {
|
private fun <T : Task> Task.wraps(other: TaskProvider<T>) {
|
||||||
@@ -203,19 +209,24 @@ private fun <T : Task> Task.wraps(other: TaskProvider<T>) {
|
|||||||
outputs.files(other)
|
outputs.files(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
val testNative by tasks.existing { dependsOn(testStartNativeExecutable, checkGlibc) }
|
val testNative = tasks.named("testNative") { dependsOn(testStartNativeExecutable, checkGlibc) }
|
||||||
|
|
||||||
val assembleNativeMacOsAarch64 by tasks.existing { wraps(macExecutableAarch64) }
|
val assembleNativeMacOsAarch64 =
|
||||||
|
tasks.named("assembleNativeMacOsAarch64") { wraps(macExecutableAarch64) }
|
||||||
|
|
||||||
val assembleNativeMacOsAmd64 by tasks.existing { wraps(macExecutableAmd64) }
|
val assembleNativeMacOsAmd64 = tasks.named("assembleNativeMacOsAmd64") { wraps(macExecutableAmd64) }
|
||||||
|
|
||||||
val assembleNativeLinuxAarch64 by tasks.existing { wraps(linuxExecutableAarch64) }
|
val assembleNativeLinuxAarch64 =
|
||||||
|
tasks.named("assembleNativeLinuxAarch64") { wraps(linuxExecutableAarch64) }
|
||||||
|
|
||||||
val assembleNativeLinuxAmd64 by tasks.existing { wraps(linuxExecutableAmd64) }
|
val assembleNativeLinuxAmd64 =
|
||||||
|
tasks.named("assembleNativeLinuxAmd64") { wraps(linuxExecutableAmd64) }
|
||||||
|
|
||||||
val assembleNativeAlpineLinuxAmd64 by tasks.existing { wraps(alpineExecutableAmd64) }
|
val assembleNativeAlpineLinuxAmd64 =
|
||||||
|
tasks.named("assembleNativeAlpineLinuxAmd64") { wraps(alpineExecutableAmd64) }
|
||||||
|
|
||||||
val assembleNativeWindowsAmd64 by tasks.existing { wraps(windowsExecutableAmd64) }
|
val assembleNativeWindowsAmd64 =
|
||||||
|
tasks.named("assembleNativeWindowsAmd64") { wraps(windowsExecutableAmd64) }
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
publications {
|
publications {
|
||||||
|
|||||||
@@ -13,29 +13,31 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
val assembleNativeMacOsAarch64 by tasks.registering { group = "build" }
|
val assembleNativeMacOsAarch64 = tasks.register("assembleNativeMacOsAarch64") { group = "build" }
|
||||||
|
|
||||||
val assembleNativeMacOsAmd64 by tasks.registering { group = "build" }
|
val assembleNativeMacOsAmd64 = tasks.register("assembleNativeMacOsAmd64") { group = "build" }
|
||||||
|
|
||||||
val assembleNativeLinuxAarch64 by tasks.registering { group = "build" }
|
val assembleNativeLinuxAarch64 = tasks.register("assembleNativeLinuxAarch64") { group = "build" }
|
||||||
|
|
||||||
val assembleNativeLinuxAmd64 by tasks.registering { group = "build" }
|
val assembleNativeLinuxAmd64 = tasks.register("assembleNativeLinuxAmd64") { group = "build" }
|
||||||
|
|
||||||
val assembleNativeAlpineLinuxAmd64 by tasks.registering { group = "build" }
|
val assembleNativeAlpineLinuxAmd64 =
|
||||||
|
tasks.register("assembleNativeAlpineLinuxAmd64") { group = "build" }
|
||||||
|
|
||||||
val assembleNativeWindowsAmd64 by tasks.registering { group = "build" }
|
val assembleNativeWindowsAmd64 = tasks.register("assembleNativeWindowsAmd64") { group = "build" }
|
||||||
|
|
||||||
val testNativeMacOsAarch64 by tasks.registering { group = "verification" }
|
val testNativeMacOsAarch64 = tasks.register("testNativeMacOsAarch64") { group = "verification" }
|
||||||
|
|
||||||
val testNativeMacOsAmd64 by tasks.registering { group = "verification" }
|
val testNativeMacOsAmd64 = tasks.register("testNativeMacOsAmd64") { group = "verification" }
|
||||||
|
|
||||||
val testNativeLinuxAarch64 by tasks.registering { group = "verification" }
|
val testNativeLinuxAarch64 = tasks.register("testNativeLinuxAarch64") { group = "verification" }
|
||||||
|
|
||||||
val testNativeLinuxAmd64 by tasks.registering { group = "verification" }
|
val testNativeLinuxAmd64 = tasks.register("testNativeLinuxAmd64") { group = "verification" }
|
||||||
|
|
||||||
val testNativeAlpineLinuxAmd64 by tasks.registering { group = "verification" }
|
val testNativeAlpineLinuxAmd64 =
|
||||||
|
tasks.register("testNativeAlpineLinuxAmd64") { group = "verification" }
|
||||||
|
|
||||||
val testNativeWindowsAmd64 by tasks.registering { group = "verification" }
|
val testNativeWindowsAmd64 = tasks.register("testNativeWindowsAmd64") { group = "verification" }
|
||||||
|
|
||||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||||
|
|
||||||
@@ -44,79 +46,85 @@ private fun <T : Task> Task.wraps(other: TaskProvider<T>) {
|
|||||||
outputs.files(other)
|
outputs.files(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
val assembleNative by tasks.registering {
|
val assembleNative =
|
||||||
group = "build"
|
tasks.register("assembleNative") {
|
||||||
|
group = "build"
|
||||||
|
|
||||||
if (!buildInfo.isCrossArchSupported && buildInfo.isCrossArch) {
|
if (!buildInfo.isCrossArchSupported && buildInfo.isCrossArch) {
|
||||||
throw GradleException("Cross-arch builds are not supported on ${buildInfo.os.name}")
|
throw GradleException("Cross-arch builds are not supported on ${buildInfo.os.name}")
|
||||||
}
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
buildInfo.os.isMacOsX && buildInfo.targetArch == "aarch64" -> {
|
buildInfo.os.isMacOsX && buildInfo.targetArch == "aarch64" -> {
|
||||||
wraps(assembleNativeMacOsAarch64)
|
wraps(assembleNativeMacOsAarch64)
|
||||||
}
|
}
|
||||||
buildInfo.os.isMacOsX && buildInfo.targetArch == "amd64" -> {
|
buildInfo.os.isMacOsX && buildInfo.targetArch == "amd64" -> {
|
||||||
wraps(assembleNativeMacOsAmd64)
|
wraps(assembleNativeMacOsAmd64)
|
||||||
}
|
}
|
||||||
buildInfo.os.isLinux && buildInfo.targetArch == "aarch64" -> {
|
buildInfo.os.isLinux && buildInfo.targetArch == "aarch64" -> {
|
||||||
wraps(assembleNativeLinuxAarch64)
|
wraps(assembleNativeLinuxAarch64)
|
||||||
}
|
}
|
||||||
buildInfo.os.isLinux && buildInfo.targetArch == "amd64" -> {
|
buildInfo.os.isLinux && buildInfo.targetArch == "amd64" -> {
|
||||||
if (buildInfo.musl) wraps(assembleNativeAlpineLinuxAmd64) else wraps(assembleNativeLinuxAmd64)
|
if (buildInfo.musl) wraps(assembleNativeAlpineLinuxAmd64)
|
||||||
}
|
else wraps(assembleNativeLinuxAmd64)
|
||||||
buildInfo.os.isWindows && buildInfo.targetArch == "amd64" -> {
|
}
|
||||||
wraps(assembleNativeWindowsAmd64)
|
buildInfo.os.isWindows && buildInfo.targetArch == "amd64" -> {
|
||||||
}
|
wraps(assembleNativeWindowsAmd64)
|
||||||
else -> {
|
}
|
||||||
doLast {
|
else -> {
|
||||||
throw GradleException(
|
doLast {
|
||||||
"Cannot build targeting ${buildInfo.os.name}/${buildInfo.targetArch} with musl=${buildInfo.musl}"
|
throw GradleException(
|
||||||
)
|
"Cannot build targeting ${buildInfo.os.name}/${buildInfo.targetArch} with musl=${buildInfo.musl}"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val testNative by tasks.registering {
|
val testNative =
|
||||||
group = "verification"
|
tasks.register("testNative") {
|
||||||
dependsOn(assembleNative)
|
group = "verification"
|
||||||
|
dependsOn(assembleNative)
|
||||||
|
|
||||||
if (!buildInfo.isCrossArchSupported && buildInfo.isCrossArch) {
|
if (!buildInfo.isCrossArchSupported && buildInfo.isCrossArch) {
|
||||||
throw GradleException("Cross-arch builds are not supported on ${buildInfo.os.name}")
|
throw GradleException("Cross-arch builds are not supported on ${buildInfo.os.name}")
|
||||||
}
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
buildInfo.os.isMacOsX && buildInfo.targetArch == "aarch64" -> {
|
buildInfo.os.isMacOsX && buildInfo.targetArch == "aarch64" -> {
|
||||||
dependsOn(testNativeMacOsAarch64)
|
dependsOn(testNativeMacOsAarch64)
|
||||||
}
|
}
|
||||||
buildInfo.os.isMacOsX && buildInfo.targetArch == "amd64" -> {
|
buildInfo.os.isMacOsX && buildInfo.targetArch == "amd64" -> {
|
||||||
dependsOn(testNativeMacOsAmd64)
|
dependsOn(testNativeMacOsAmd64)
|
||||||
}
|
}
|
||||||
buildInfo.os.isLinux && buildInfo.targetArch == "aarch64" -> {
|
buildInfo.os.isLinux && buildInfo.targetArch == "aarch64" -> {
|
||||||
dependsOn(testNativeLinuxAarch64)
|
dependsOn(testNativeLinuxAarch64)
|
||||||
}
|
}
|
||||||
buildInfo.os.isLinux && buildInfo.targetArch == "amd64" -> {
|
buildInfo.os.isLinux && buildInfo.targetArch == "amd64" -> {
|
||||||
if (buildInfo.musl) dependsOn(testNativeAlpineLinuxAmd64) else dependsOn(testNativeLinuxAmd64)
|
if (buildInfo.musl) dependsOn(testNativeAlpineLinuxAmd64)
|
||||||
}
|
else dependsOn(testNativeLinuxAmd64)
|
||||||
buildInfo.os.isWindows && buildInfo.targetArch == "amd64" -> {
|
}
|
||||||
dependsOn(testNativeWindowsAmd64)
|
buildInfo.os.isWindows && buildInfo.targetArch == "amd64" -> {
|
||||||
}
|
dependsOn(testNativeWindowsAmd64)
|
||||||
else -> {
|
}
|
||||||
doLast {
|
else -> {
|
||||||
throw GradleException(
|
doLast {
|
||||||
"Cannot build targeting ${buildInfo.os.name}/${buildInfo.targetArch} with musl=${buildInfo.musl}"
|
throw GradleException(
|
||||||
)
|
"Cannot build targeting ${buildInfo.os.name}/${buildInfo.targetArch} with musl=${buildInfo.musl}"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val checkNative by tasks.registering {
|
val checkNative =
|
||||||
group = "verification"
|
tasks.register("checkNative") {
|
||||||
dependsOn(testNative)
|
group = "verification"
|
||||||
}
|
dependsOn(testNative)
|
||||||
|
}
|
||||||
|
|
||||||
val buildNative by tasks.registering {
|
val buildNative =
|
||||||
group = "build"
|
tasks.register("buildNative") {
|
||||||
dependsOn(checkNative)
|
group = "build"
|
||||||
}
|
dependsOn(checkNative)
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
plugins { id("com.diffplug.spotless") }
|
plugins { id("com.diffplug.spotless") }
|
||||||
|
|
||||||
val pklFormatter by configurations.creating
|
val pklFormatter = configurations.create("pklFormatter")
|
||||||
|
|
||||||
dependencies { pklFormatter(rootProject.project("pkl-formatter")) }
|
dependencies { pklFormatter(rootProject.project("pkl-formatter")) }
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -37,7 +37,8 @@ nexusPublishing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val configureLateInitAnnotation by tasks.registering(ConfigureLateInitAnnotation::class)
|
val configureLateInitAnnotation =
|
||||||
|
tasks.register<ConfigureLateInitAnnotation>("configureLateInitAnnotation")
|
||||||
|
|
||||||
idea {
|
idea {
|
||||||
project {
|
project {
|
||||||
@@ -53,9 +54,9 @@ idea {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val clean by tasks.existing { delete(layout.buildDirectory) }
|
val clean = tasks.named("clean") { delete(layout.buildDirectory) }
|
||||||
|
|
||||||
val printVersion by tasks.registering { doFirst { println(buildInfo.pklVersion) } }
|
val printVersion = tasks.register("printVersion") { doFirst { println(buildInfo.pklVersion) } }
|
||||||
|
|
||||||
val message =
|
val message =
|
||||||
"""
|
"""
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
name: main
|
name: main
|
||||||
title: Main Project
|
title: Main Project
|
||||||
version: 0.32.0-dev
|
version: 0.32.2
|
||||||
prerelease: true
|
prerelease: false
|
||||||
nav:
|
nav:
|
||||||
- nav.adoc
|
- nav.adoc
|
||||||
@@ -3,10 +3,10 @@
|
|||||||
// the following attributes must be updated immediately before a release
|
// the following attributes must be updated immediately before a release
|
||||||
|
|
||||||
// pkl version corresponding to current git commit without -dev suffix or git hash
|
// pkl version corresponding to current git commit without -dev suffix or git hash
|
||||||
:pkl-version-no-suffix: 0.32.0
|
:pkl-version-no-suffix: 0.32.2
|
||||||
// tells whether pkl version corresponding to current git commit
|
// tells whether pkl version corresponding to current git commit
|
||||||
// is a release version (:is-release-version: '') or dev version (:!is-release-version:)
|
// is a release version (:is-release-version: '') or dev version (:!is-release-version:)
|
||||||
:!is-release-version:
|
:is-release-version: ''
|
||||||
|
|
||||||
// the remaining attributes do not need to be updated regularly
|
// the remaining attributes do not need to be updated regularly
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
= Pkl 0.32 Release Notes
|
= Pkl 0.32 Release Notes
|
||||||
:version: 0.32
|
:version: 0.32
|
||||||
:version-minor: 0.32.0
|
:version-minor: 0.32.2
|
||||||
:release-date: July 8th, 2026
|
:release-date: July 8th, 2026
|
||||||
:version-next: 0.33
|
:version-next: 0.33
|
||||||
:version-next-date: October 2026
|
:version-next-date: October 2026
|
||||||
|
|||||||
@@ -1,8 +1,44 @@
|
|||||||
= Changelog
|
= Changelog
|
||||||
include::ROOT:partial$component-attributes.adoc[]
|
include::ROOT:partial$component-attributes.adoc[]
|
||||||
|
|
||||||
|
[[release-0.32.2]]
|
||||||
|
== 0.32.2 (2026-10-21)
|
||||||
|
|
||||||
|
=== Security Fixes [small]#🔒#
|
||||||
|
|
||||||
|
* Update fallback CA certificate trust and remove trust for the issuer of compromised intermediate CAs (pr:https://github.com/apple/pkl/pull/1923).
|
||||||
|
|
||||||
|
=== Fixes
|
||||||
|
|
||||||
|
* Fix rendering of stack traces for evaluated multi-line expressions (pr:https://github.com/apple/pkl/pull/1793).
|
||||||
|
|
||||||
|
=== Contributors ❤️
|
||||||
|
|
||||||
|
Thank you to all the contributors for this release!
|
||||||
|
|
||||||
|
* https://github.com/HT154[@HT154]
|
||||||
|
* https://github.com/protobufel2[@protobufel2]
|
||||||
|
|
||||||
|
[[release-0.32.1]]
|
||||||
|
== 0.32.1 (2026-07-23)
|
||||||
|
|
||||||
|
=== Fixes
|
||||||
|
|
||||||
|
* Fix closing intermediate response bodies when following HTTP redirects (https://github.com/apple/pkl/pull/1749[#1749]).
|
||||||
|
* Fix `eval -x` of local members (https://github.com/apple/pkl/pull/1760[#1760]).
|
||||||
|
* Fix variable resolution of object body params (https://github.com/apple/pkl/pull/1788[#1788]).
|
||||||
|
|
||||||
|
=== Contributors ❤️
|
||||||
|
|
||||||
|
Thank you to all the contributors for this release!
|
||||||
|
|
||||||
|
* https://github.com/bioball[@bioball]
|
||||||
|
* https://github.com/KushalP[@KushalP]
|
||||||
|
|
||||||
[[release-0.32.0]]
|
[[release-0.32.0]]
|
||||||
== 0.32.0 (UNRELEASED)
|
== 0.32.0 (2026-07-08)
|
||||||
|
|
||||||
|
xref:0.32.adoc[Release Notes]
|
||||||
|
|
||||||
[[release-0.31.1]]
|
[[release-0.31.1]]
|
||||||
== 0.31.1 (2026-03-26)
|
== 0.31.1 (2026-03-26)
|
||||||
@@ -38,6 +74,7 @@ Thank you to all the contributors for this release!
|
|||||||
== 0.31.0 (2026-02-26)
|
== 0.31.0 (2026-02-26)
|
||||||
|
|
||||||
xref:0.31.adoc[Release Notes]
|
xref:0.31.adoc[Release Notes]
|
||||||
|
|
||||||
[[release-0.30.2]]
|
[[release-0.30.2]]
|
||||||
|
|
||||||
== 0.30.2 (2025-12-15)
|
== 0.30.2 (2025-12-15)
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
# suppress inspection "UnusedProperty" for whole file
|
# suppress inspection "UnusedProperty" for whole file
|
||||||
|
|
||||||
group=org.pkl-lang
|
group=org.pkl-lang
|
||||||
version=0.32.0
|
version=0.32.2
|
||||||
|
|
||||||
# google-java-format requires jdk.compiler exports
|
# google-java-format requires jdk.compiler exports
|
||||||
org.gradle.jvmargs= \
|
org.gradle.jvmargs= \
|
||||||
|
|||||||
+3
-3
@@ -2,15 +2,15 @@
|
|||||||
"catalogs": {},
|
"catalogs": {},
|
||||||
"aliases": {
|
"aliases": {
|
||||||
"pkl": {
|
"pkl": {
|
||||||
"script-ref": "org.pkl-lang:pkl-cli-java:0.31.1",
|
"script-ref": "org.pkl-lang:pkl-cli-java:0.32.2",
|
||||||
"java-agents": []
|
"java-agents": []
|
||||||
},
|
},
|
||||||
"pkl-codegen-java": {
|
"pkl-codegen-java": {
|
||||||
"script-ref": "org.pkl-lang:pkl-codegen-java:0.31.1",
|
"script-ref": "org.pkl-lang:pkl-codegen-java:0.32.2",
|
||||||
"java-agents": []
|
"java-agents": []
|
||||||
},
|
},
|
||||||
"pkl-codegen-kotlin": {
|
"pkl-codegen-kotlin": {
|
||||||
"script-ref": "org.pkl-lang:pkl-codegen-kotlin:0.31.1",
|
"script-ref": "org.pkl-lang:pkl-codegen-kotlin:0.32.2",
|
||||||
"java-agents": []
|
"java-agents": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -83,8 +83,8 @@ tasks.shadowJar {
|
|||||||
exclude("module-info.*")
|
exclude("module-info.*")
|
||||||
}
|
}
|
||||||
|
|
||||||
val testJavaExecutable by
|
val testJavaExecutable =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testJavaExecutable") {
|
||||||
testClassesDirs = tasks.test.get().testClassesDirs
|
testClassesDirs = tasks.test.get().testClassesDirs
|
||||||
classpath =
|
classpath =
|
||||||
// compiled test classes
|
// compiled test classes
|
||||||
@@ -138,7 +138,7 @@ fun Exec.useRootDirAndSuppressOutput() {
|
|||||||
|
|
||||||
// 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
|
||||||
// the evaluator fails. To catch this, we eval a simple expression using the fat jar.
|
// the evaluator fails. To catch this, we eval a simple expression using the fat jar.
|
||||||
val testEvalJavaExecutable by
|
val testEvalJavaExecutable =
|
||||||
setupJavaExecutableRun("testEvalJavaExecutable", evalTestFlags) { useRootDirAndSuppressOutput() }
|
setupJavaExecutableRun("testEvalJavaExecutable", evalTestFlags) { useRootDirAndSuppressOutput() }
|
||||||
|
|
||||||
// Run the same evaluator tests on all configured JDK test versions.
|
// Run the same evaluator tests on all configured JDK test versions.
|
||||||
|
|||||||
@@ -1777,7 +1777,7 @@ result = someLib.x
|
|||||||
PackageServer.populateCacheDir(tempDir)
|
PackageServer.populateCacheDir(tempDir)
|
||||||
val projectPath =
|
val projectPath =
|
||||||
FileTestUtils.rootProjectDir.resolve(
|
FileTestUtils.rootProjectDir.resolve(
|
||||||
"pkl-commons-cli/src/main/resources/org/pkl/commons/cli/project1/"
|
"pkl-commons-cli/src/test/resources/org/pkl/commons/cli/project1/"
|
||||||
)
|
)
|
||||||
val options =
|
val options =
|
||||||
CliEvaluatorOptions(
|
CliEvaluatorOptions(
|
||||||
|
|||||||
@@ -19,10 +19,11 @@ plugins {
|
|||||||
id("pklPublishLibrary")
|
id("pklPublishLibrary")
|
||||||
}
|
}
|
||||||
|
|
||||||
val svmClasspath: Configuration by configurations.creating
|
val svmClasspath: Configuration = configurations.create("svmClasspath")
|
||||||
|
|
||||||
// used by pklNativeExecutable.gradle.kts
|
// used by pklNativeExecutable.gradle.kts
|
||||||
@Suppress("unused") val svm: SourceSet by sourceSets.creating { compileClasspath = svmClasspath }
|
@Suppress("unused")
|
||||||
|
val svm: SourceSet = sourceSets.create("svm") { compileClasspath = svmClasspath }
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(projects.pklCore)
|
api(projects.pklCore)
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
File renamed without changes.
File renamed without changes.
@@ -37,7 +37,7 @@ dependencies {
|
|||||||
* These packages are used by PackageServer to serve assets when running LanguageSnippetTests and
|
* These packages are used by PackageServer to serve assets when running LanguageSnippetTests and
|
||||||
* PackageResolversTest.
|
* PackageResolversTest.
|
||||||
*/
|
*/
|
||||||
val createTestPackages by tasks.registering
|
val createTestPackages = tasks.register("createTestPackages")
|
||||||
|
|
||||||
// make sure that declaring a dependency on this project suffices to have test fixtures generated
|
// make sure that declaring a dependency on this project suffices to have test fixtures generated
|
||||||
tasks.processResources {
|
tasks.processResources {
|
||||||
@@ -92,8 +92,8 @@ val keystoreName = "localhost.p12"
|
|||||||
val keystoreFile = keystoreDir.map { it.file(keystoreName) }
|
val keystoreFile = keystoreDir.map { it.file(keystoreName) }
|
||||||
val certsFileName = "localhost.pem"
|
val certsFileName = "localhost.pem"
|
||||||
|
|
||||||
val generateKeys by
|
val generateKeys =
|
||||||
tasks.registering(JavaExec::class) {
|
tasks.register<JavaExec>("generateKeys") {
|
||||||
outputs.file(keystoreFile)
|
outputs.file(keystoreFile)
|
||||||
mainClass.set("sun.security.tools.keytool.Main")
|
mainClass.set("sun.security.tools.keytool.Main")
|
||||||
args =
|
args =
|
||||||
@@ -117,8 +117,8 @@ val generateKeys by
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val exportCerts by
|
val exportCerts =
|
||||||
tasks.registering(JavaExec::class) {
|
tasks.register<JavaExec>("exportCerts") {
|
||||||
val outputFile = keystoreDir.map { it.file(certsFileName) }
|
val outputFile = keystoreDir.map { it.file(certsFileName) }
|
||||||
dependsOn(generateKeys)
|
dependsOn(generateKeys)
|
||||||
inputs.file(keystoreFile)
|
inputs.file(keystoreFile)
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ plugins {
|
|||||||
signing
|
signing
|
||||||
}
|
}
|
||||||
|
|
||||||
val pklCodegenJava: Configuration by configurations.creating
|
val pklCodegenJava: Configuration = configurations.create("pklCodegenJava")
|
||||||
val firstPartySourcesJars by configurations.existing
|
val firstPartySourcesJars = configurations.named("firstPartySourcesJars")
|
||||||
|
|
||||||
val generateTestConfigClasses by
|
val generateTestConfigClasses =
|
||||||
tasks.registering(JavaExec::class) {
|
tasks.register<JavaExec>("generateTestConfigClasses") {
|
||||||
val outputDir = layout.buildDirectory.dir("testConfigClasses")
|
val outputDir = layout.buildDirectory.dir("testConfigClasses")
|
||||||
outputs.dir(outputDir)
|
outputs.dir(outputDir)
|
||||||
inputs.dir("src/test/resources/codegenPkl")
|
inputs.dir("src/test/resources/codegenPkl")
|
||||||
@@ -45,13 +45,13 @@ tasks.processTestResources { dependsOn(generateTestConfigClasses) }
|
|||||||
|
|
||||||
tasks.compileTestKotlin { dependsOn(generateTestConfigClasses) }
|
tasks.compileTestKotlin { dependsOn(generateTestConfigClasses) }
|
||||||
|
|
||||||
val bundleTests by tasks.registering(Jar::class) { from(sourceSets.test.get().output) }
|
val bundleTests = tasks.register<Jar>("bundleTests") { from(sourceSets.test.get().output) }
|
||||||
|
|
||||||
// Runs unit tests using jar'd class files as a source.
|
// Runs unit tests using jar'd class files as a source.
|
||||||
// This is to test loading the ClassRegistry from within a jar, as opposed to directly from the file
|
// This is to test loading the ClassRegistry from within a jar, as opposed to directly from the file
|
||||||
// system.
|
// system.
|
||||||
val testFromJar by
|
val testFromJar =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testFromJar") {
|
||||||
dependsOn(bundleTests)
|
dependsOn(bundleTests)
|
||||||
|
|
||||||
testClassesDirs = files(tasks.test.get().testClassesDirs)
|
testClassesDirs = files(tasks.test.get().testClassesDirs)
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ plugins {
|
|||||||
id("pklPublishLibrary")
|
id("pklPublishLibrary")
|
||||||
}
|
}
|
||||||
|
|
||||||
val pklConfigJava: Configuration by configurations.creating
|
val pklConfigJava: Configuration = configurations.create("pklConfigJava")
|
||||||
|
|
||||||
val pklConfigJavaAll: Configuration by configurations.creating
|
val pklConfigJavaAll: Configuration = configurations.create("pklConfigJavaAll")
|
||||||
|
|
||||||
val pklCodegenKotlin: Configuration by configurations.creating
|
val pklCodegenKotlin: Configuration = configurations.create("pklCodegenKotlin")
|
||||||
|
|
||||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||||
|
|
||||||
@@ -49,8 +49,8 @@ dependencies {
|
|||||||
testImplementation(libs.geantyref)
|
testImplementation(libs.geantyref)
|
||||||
}
|
}
|
||||||
|
|
||||||
val generateTestConfigClasses by
|
val generateTestConfigClasses =
|
||||||
tasks.registering(JavaExec::class) {
|
tasks.register<JavaExec>("generateTestConfigClasses") {
|
||||||
val outputDir = layout.buildDirectory.dir("testConfigClasses")
|
val outputDir = layout.buildDirectory.dir("testConfigClasses")
|
||||||
outputs.dir(outputDir)
|
outputs.dir(outputDir)
|
||||||
inputs.dir("src/test/resources/codegenPkl")
|
inputs.dir("src/test/resources/codegenPkl")
|
||||||
|
|||||||
@@ -35,9 +35,10 @@ val externalReaderFixtureSourceSet: NamedDomainObjectProvider<SourceSet> =
|
|||||||
runtimeClasspath += sourceSets.test.get().output + sourceSets.test.get().runtimeClasspath
|
runtimeClasspath += sourceSets.test.get().output + sourceSets.test.get().runtimeClasspath
|
||||||
}
|
}
|
||||||
|
|
||||||
val externalReaderFixtureImplementation: Configuration by configurations.getting {
|
val externalReaderFixtureImplementation: Configuration =
|
||||||
extendsFrom(configurations.testImplementation.get())
|
configurations.getByName("externalReaderFixtureImplementation") {
|
||||||
}
|
extendsFrom(configurations.testImplementation.get())
|
||||||
|
}
|
||||||
|
|
||||||
idea {
|
idea {
|
||||||
module {
|
module {
|
||||||
@@ -137,36 +138,37 @@ tasks.withType<JavaCompile>().configureEach {
|
|||||||
|
|
||||||
tasks.compileKotlin { enabled = false }
|
tasks.compileKotlin { enabled = false }
|
||||||
|
|
||||||
val externalReaderFixture by tasks.registering {
|
val externalReaderFixture =
|
||||||
group = "build"
|
tasks.register("externalReaderFixture") {
|
||||||
dependsOn(tasks.named("compileExternalReaderFixtureJava"))
|
group = "build"
|
||||||
inputs.files(externalReaderFixtureSourceSet.map { it.output })
|
dependsOn(tasks.named("compileExternalReaderFixtureJava"))
|
||||||
val fileName = if (buildInfo.os.isWindows) "externalreader.bat" else "externalreader"
|
inputs.files(externalReaderFixtureSourceSet.map { it.output })
|
||||||
val outputFile = layout.buildDirectory.file("fixtures/$fileName")
|
val fileName = if (buildInfo.os.isWindows) "externalreader.bat" else "externalreader"
|
||||||
outputs.file(outputFile)
|
val outputFile = layout.buildDirectory.file("fixtures/$fileName")
|
||||||
doLast {
|
outputs.file(outputFile)
|
||||||
val classpath = externalReaderFixtureSourceSet.get().runtimeClasspath.asPath
|
doLast {
|
||||||
val scriptContent =
|
val classpath = externalReaderFixtureSourceSet.get().runtimeClasspath.asPath
|
||||||
if (buildInfo.os.isWindows) {
|
val scriptContent =
|
||||||
"""
|
if (buildInfo.os.isWindows) {
|
||||||
|
"""
|
||||||
@echo off
|
@echo off
|
||||||
java -cp $classpath org.pkl.core.externalreaderfixture.Main
|
java -cp $classpath org.pkl.core.externalreaderfixture.Main
|
||||||
"""
|
"""
|
||||||
.trimIndent()
|
.trimIndent()
|
||||||
} else {
|
} else {
|
||||||
"""
|
"""
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
java -cp $classpath org.pkl.core.externalreaderfixture.Main
|
java -cp $classpath org.pkl.core.externalreaderfixture.Main
|
||||||
"""
|
"""
|
||||||
.trimIndent()
|
.trimIndent()
|
||||||
}
|
}
|
||||||
|
|
||||||
outputFile.get().asFile.writeText(scriptContent)
|
outputFile.get().asFile.writeText(scriptContent)
|
||||||
outputFile.get().asFile.setExecutable(true)
|
outputFile.get().asFile.setExecutable(true)
|
||||||
println("Created external reader ${outputFile.get().asFile.absolutePath}")
|
println("Created external reader ${outputFile.get().asFile.absolutePath}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
tasks.test {
|
tasks.test {
|
||||||
configureTest()
|
configureTest()
|
||||||
@@ -194,8 +196,8 @@ tasks.test {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val generateBaseModuleMembers by
|
val generateBaseModuleMembers =
|
||||||
tasks.registering(JavaExec::class) {
|
tasks.register<JavaExec>("generateBaseModuleMembers") {
|
||||||
group = "build"
|
group = "build"
|
||||||
|
|
||||||
val outputDir = layout.buildDirectory.dir("generated/sources/baseModuleMembers")
|
val outputDir = layout.buildDirectory.dir("generated/sources/baseModuleMembers")
|
||||||
@@ -226,8 +228,8 @@ tasks.compileJava { dependsOn(generateBaseModuleMembers) }
|
|||||||
|
|
||||||
tasks.sourcesJar { dependsOn(generateBaseModuleMembers) }
|
tasks.sourcesJar { dependsOn(generateBaseModuleMembers) }
|
||||||
|
|
||||||
val testJavaExecutable by
|
val testJavaExecutable =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testJavaExecutable") {
|
||||||
configureExecutableTest("LanguageSnippetTestsEngine")
|
configureExecutableTest("LanguageSnippetTestsEngine")
|
||||||
classpath =
|
classpath =
|
||||||
// compiled test classes
|
// compiled test classes
|
||||||
@@ -246,38 +248,38 @@ val testJavaExecutable by
|
|||||||
|
|
||||||
tasks.check { dependsOn(testJavaExecutable) }
|
tasks.check { dependsOn(testJavaExecutable) }
|
||||||
|
|
||||||
val testMacExecutableAmd64 by
|
val testMacExecutableAmd64 =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testMacExecutableAmd64") {
|
||||||
dependsOn(":pkl-cli:macExecutableAmd64")
|
dependsOn(":pkl-cli:macExecutableAmd64")
|
||||||
configureExecutableTest("MacAmd64LanguageSnippetTestsEngine")
|
configureExecutableTest("MacAmd64LanguageSnippetTestsEngine")
|
||||||
}
|
}
|
||||||
|
|
||||||
val testMacExecutableAarch64 by
|
val testMacExecutableAarch64 =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testMacExecutableAarch64") {
|
||||||
dependsOn(":pkl-cli:macExecutableAarch64")
|
dependsOn(":pkl-cli:macExecutableAarch64")
|
||||||
configureExecutableTest("MacAarch64LanguageSnippetTestsEngine")
|
configureExecutableTest("MacAarch64LanguageSnippetTestsEngine")
|
||||||
}
|
}
|
||||||
|
|
||||||
val testLinuxExecutableAmd64 by
|
val testLinuxExecutableAmd64 =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testLinuxExecutableAmd64") {
|
||||||
dependsOn(":pkl-cli:linuxExecutableAmd64")
|
dependsOn(":pkl-cli:linuxExecutableAmd64")
|
||||||
configureExecutableTest("LinuxAmd64LanguageSnippetTestsEngine")
|
configureExecutableTest("LinuxAmd64LanguageSnippetTestsEngine")
|
||||||
}
|
}
|
||||||
|
|
||||||
val testLinuxExecutableAarch64 by
|
val testLinuxExecutableAarch64 =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testLinuxExecutableAarch64") {
|
||||||
dependsOn(":pkl-cli:linuxExecutableAarch64")
|
dependsOn(":pkl-cli:linuxExecutableAarch64")
|
||||||
configureExecutableTest("LinuxAarch64LanguageSnippetTestsEngine")
|
configureExecutableTest("LinuxAarch64LanguageSnippetTestsEngine")
|
||||||
}
|
}
|
||||||
|
|
||||||
val testAlpineExecutableAmd64 by
|
val testAlpineExecutableAmd64 =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testAlpineExecutableAmd64") {
|
||||||
dependsOn(":pkl-cli:alpineExecutableAmd64")
|
dependsOn(":pkl-cli:alpineExecutableAmd64")
|
||||||
configureExecutableTest("AlpineLanguageSnippetTestsEngine")
|
configureExecutableTest("AlpineLanguageSnippetTestsEngine")
|
||||||
}
|
}
|
||||||
|
|
||||||
val testWindowsExecutableAmd64 by
|
val testWindowsExecutableAmd64 =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testWindowsExecutableAmd64") {
|
||||||
dependsOn(":pkl-cli:windowsExecutableAmd64")
|
dependsOn(":pkl-cli:windowsExecutableAmd64")
|
||||||
configureExecutableTest("WindowsLanguageSnippetTestsEngine")
|
configureExecutableTest("WindowsLanguageSnippetTestsEngine")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -523,6 +523,13 @@ public final class SymbolTable {
|
|||||||
if (scope instanceof LexicalScope lex) {
|
if (scope instanceof LexicalScope lex) {
|
||||||
if (shouldSkip && !(scope instanceof ForGeneratorScope)) {
|
if (shouldSkip && !(scope instanceof ForGeneratorScope)) {
|
||||||
if (scope instanceof ObjectScope objectScope && objectScope.hasParams()) {
|
if (scope instanceof ObjectScope objectScope && objectScope.hasParams()) {
|
||||||
|
// skipping the object scope should now see the object body params, because the params
|
||||||
|
// are one level higher than the body itself.
|
||||||
|
var result = fun.apply(objectScope, levelsUp);
|
||||||
|
if (result instanceof Parameter parameter) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (R) new Parameter(parameter.slot(), parameter.levelsUp() - 1);
|
||||||
|
}
|
||||||
levelsUp++;
|
levelsUp++;
|
||||||
}
|
}
|
||||||
// An EagerGeneratorScope (for `when` predicates) skipped an ObjectScope.
|
// An EagerGeneratorScope (for `when` predicates) skipped an ObjectScope.
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
package org.pkl.core.http;
|
package org.pkl.core.http;
|
||||||
|
|
||||||
import com.google.errorprone.annotations.ThreadSafe;
|
import com.google.errorprone.annotations.ThreadSafe;
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
@@ -118,6 +119,9 @@ final class RequestRewritingClient implements HttpClient {
|
|||||||
if (!HttpUtils.isRedirectStatusCode(response.statusCode())) {
|
if (!HttpUtils.isRedirectStatusCode(response.statusCode())) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
if (response.body() instanceof Closeable closeable) {
|
||||||
|
closeable.close();
|
||||||
|
}
|
||||||
if (redirectCount >= MAX_HTTP_REDIRECTS) {
|
if (redirectCount >= MAX_HTTP_REDIRECTS) {
|
||||||
throw new HttpClientException(
|
throw new HttpClientException(
|
||||||
ErrorMessages.create("httpTooManyRedirects", MAX_HTTP_REDIRECTS));
|
ErrorMessages.create("httpTooManyRedirects", MAX_HTTP_REDIRECTS));
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ import org.pkl.core.util.AnsiStringBuilder;
|
|||||||
import org.pkl.core.util.EconomicMaps;
|
import org.pkl.core.util.EconomicMaps;
|
||||||
import org.pkl.core.util.IoUtils;
|
import org.pkl.core.util.IoUtils;
|
||||||
import org.pkl.core.util.MutableReference;
|
import org.pkl.core.util.MutableReference;
|
||||||
import org.pkl.core.util.Pair;
|
|
||||||
import org.pkl.core.util.SyntaxHighlighter;
|
import org.pkl.core.util.SyntaxHighlighter;
|
||||||
import org.pkl.parser.Parser;
|
import org.pkl.parser.Parser;
|
||||||
import org.pkl.parser.ParserError;
|
import org.pkl.parser.ParserError;
|
||||||
@@ -183,51 +182,6 @@ public class ReplServer implements AutoCloseable {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a fake module that declares all the local properties that exist in ReplState, so that
|
|
||||||
* AstBuilder can correctly resolve variables. Additionally, return a {@link Node} with its span
|
|
||||||
* calculated in terms of this fake module.
|
|
||||||
*
|
|
||||||
* <p>This created module is never executed.
|
|
||||||
*/
|
|
||||||
private Pair<String, Node> buildSyntheticModuleText(Node syntaxNode, String srcText) {
|
|
||||||
if (syntaxNode instanceof ModuleDecl) {
|
|
||||||
return Pair.of(srcText, syntaxNode);
|
|
||||||
}
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
var nodeText = syntaxNode.text(srcText.toCharArray());
|
|
||||||
var adjustedNode = syntaxNode;
|
|
||||||
if (syntaxNode instanceof Expr) {
|
|
||||||
sb.append(expressionPreamble).append(nodeText).append('\n');
|
|
||||||
} else {
|
|
||||||
sb.append(nodeText).append('\n');
|
|
||||||
}
|
|
||||||
var mod = parser.parseModule(sb.toString());
|
|
||||||
if (syntaxNode instanceof Expr) {
|
|
||||||
adjustedNode = mod.getProperties().get(0).getExpr();
|
|
||||||
} else if (syntaxNode instanceof ImportClause) {
|
|
||||||
adjustedNode = mod.getImports().get(0);
|
|
||||||
} else if (syntaxNode instanceof ClassProperty) {
|
|
||||||
adjustedNode = mod.getProperties().get(0);
|
|
||||||
} else if (syntaxNode instanceof Class) {
|
|
||||||
adjustedNode = mod.getClasses().get(0);
|
|
||||||
} else if (syntaxNode instanceof org.pkl.parser.syntax.TypeAlias) {
|
|
||||||
adjustedNode = mod.getTypeAliases().get(0);
|
|
||||||
} else if (syntaxNode instanceof org.pkl.parser.syntax.ClassMethod) {
|
|
||||||
adjustedNode = mod.getMethods().get(0);
|
|
||||||
}
|
|
||||||
var cursor = EconomicMaps.getEntries(replState.module.getMembers());
|
|
||||||
while (cursor.advance()) {
|
|
||||||
var key = cursor.getKey();
|
|
||||||
var value = cursor.getValue();
|
|
||||||
if (value.isLocal()) {
|
|
||||||
sb.append("local ").append(key).append(" = Undefined()\n\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert adjustedNode != null;
|
|
||||||
return Pair.of(sb.toString(), adjustedNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("StatementWithEmptyBody")
|
@SuppressWarnings("StatementWithEmptyBody")
|
||||||
private void handleNode(
|
private void handleNode(
|
||||||
ReplState replState,
|
ReplState replState,
|
||||||
@@ -237,7 +191,7 @@ public class ReplServer implements AutoCloseable {
|
|||||||
String srcText,
|
String srcText,
|
||||||
boolean evalDefinitions,
|
boolean evalDefinitions,
|
||||||
boolean forceResults) {
|
boolean forceResults) {
|
||||||
var pair = buildSyntheticModuleText(node, srcText);
|
var pair = VmUtils.buildSyntheticModuleText(node, replState.module, srcText);
|
||||||
var syntheticModuleText = pair.first;
|
var syntheticModuleText = pair.first;
|
||||||
var adjustedNode = pair.second;
|
var adjustedNode = pair.second;
|
||||||
var module = ModuleKeys.synthetic(uri, workingDir.toUri(), uri, syntheticModuleText, false);
|
var module = ModuleKeys.synthetic(uri, workingDir.toUri(), uri, syntheticModuleText, false);
|
||||||
@@ -283,8 +237,9 @@ public class ReplServer implements AutoCloseable {
|
|||||||
new ReplResponse.InternalError(new IllegalStateException("Unexpected parse result")));
|
new ReplResponse.InternalError(new IllegalStateException("Unexpected parse result")));
|
||||||
}
|
}
|
||||||
} catch (VmException e) {
|
} catch (VmException e) {
|
||||||
|
e.setForExpressionInput(true);
|
||||||
// TODO: patch stack trace for constants
|
// TODO: patch stack trace for constants
|
||||||
results.add(new EvalError(renderException(e)));
|
results.add(new EvalError(errorRenderer.render(e)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ import org.pkl.core.util.SyntaxHighlighter;
|
|||||||
public final class StackTraceRenderer {
|
public final class StackTraceRenderer {
|
||||||
private final Function<StackFrame, StackFrame> frameTransformer;
|
private final Function<StackFrame, StackFrame> frameTransformer;
|
||||||
|
|
||||||
|
private static final int PREAMBLE_LENGTH = VmUtils.EXPRESSION_PREAMBLE.length();
|
||||||
|
|
||||||
public StackTraceRenderer(Function<StackFrame, StackFrame> frameTransformer) {
|
public StackTraceRenderer(Function<StackFrame, StackFrame> frameTransformer) {
|
||||||
this.frameTransformer = frameTransformer;
|
this.frameTransformer = frameTransformer;
|
||||||
}
|
}
|
||||||
@@ -36,9 +38,10 @@ public final class StackTraceRenderer {
|
|||||||
List<StackFrame> frames,
|
List<StackFrame> frames,
|
||||||
@Nullable String hint,
|
@Nullable String hint,
|
||||||
@Nullable BiConsumer<AnsiStringBuilder, Boolean> hintBuilder,
|
@Nullable BiConsumer<AnsiStringBuilder, Boolean> hintBuilder,
|
||||||
AnsiStringBuilder out) {
|
AnsiStringBuilder out,
|
||||||
|
boolean forExpressionInput) {
|
||||||
var compressed = compressFrames(frames);
|
var compressed = compressFrames(frames);
|
||||||
doRender(compressed, hint, hintBuilder, out, "", true);
|
doRender(compressed, hint, hintBuilder, out, "", true, forExpressionInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
// non-private for testing
|
// non-private for testing
|
||||||
@@ -48,12 +51,13 @@ public final class StackTraceRenderer {
|
|||||||
@Nullable BiConsumer<AnsiStringBuilder, Boolean> hintBuilder,
|
@Nullable BiConsumer<AnsiStringBuilder, Boolean> hintBuilder,
|
||||||
AnsiStringBuilder out,
|
AnsiStringBuilder out,
|
||||||
String leftMargin,
|
String leftMargin,
|
||||||
boolean isFirstElement) {
|
boolean isFirstElement,
|
||||||
|
boolean forExpressionInput) {
|
||||||
for (var frame : frames) {
|
for (var frame : frames) {
|
||||||
if (frame instanceof StackFrameLoop loop) {
|
if (frame instanceof StackFrameLoop loop) {
|
||||||
// ensure a cycle of length 1 doesn't get rendered as a loop
|
// ensure a cycle of length 1 doesn't get rendered as a loop
|
||||||
if (loop.count == 1) {
|
if (loop.count == 1) {
|
||||||
doRender(loop.frames, null, null, out, leftMargin, isFirstElement);
|
doRender(loop.frames, null, null, out, leftMargin, isFirstElement, forExpressionInput);
|
||||||
} else {
|
} else {
|
||||||
if (!isFirstElement) {
|
if (!isFirstElement) {
|
||||||
out.append(AnsiTheme.STACK_TRACE_MARGIN, leftMargin).append('\n');
|
out.append(AnsiTheme.STACK_TRACE_MARGIN, leftMargin).append('\n');
|
||||||
@@ -63,7 +67,7 @@ public final class StackTraceRenderer {
|
|||||||
.append(AnsiTheme.STACK_TRACE_LOOP_COUNT, loop.count)
|
.append(AnsiTheme.STACK_TRACE_LOOP_COUNT, loop.count)
|
||||||
.append(" repetitions of:\n");
|
.append(" repetitions of:\n");
|
||||||
var newLeftMargin = leftMargin + "│ ";
|
var newLeftMargin = leftMargin + "│ ";
|
||||||
doRender(loop.frames, null, null, out, newLeftMargin, isFirstElement);
|
doRender(loop.frames, null, null, out, newLeftMargin, isFirstElement, forExpressionInput);
|
||||||
if (isFirstElement) {
|
if (isFirstElement) {
|
||||||
renderHint(hint, hintBuilder, out, newLeftMargin);
|
renderHint(hint, hintBuilder, out, newLeftMargin);
|
||||||
isFirstElement = false;
|
isFirstElement = false;
|
||||||
@@ -74,7 +78,7 @@ public final class StackTraceRenderer {
|
|||||||
if (!isFirstElement) {
|
if (!isFirstElement) {
|
||||||
out.append(AnsiTheme.STACK_TRACE_MARGIN, leftMargin).append('\n');
|
out.append(AnsiTheme.STACK_TRACE_MARGIN, leftMargin).append('\n');
|
||||||
}
|
}
|
||||||
renderFrame((StackFrame) frame, out, leftMargin);
|
renderFrame((StackFrame) frame, out, leftMargin, forExpressionInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFirstElement) {
|
if (isFirstElement) {
|
||||||
@@ -84,9 +88,10 @@ public final class StackTraceRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderFrame(StackFrame frame, AnsiStringBuilder out, String leftMargin) {
|
private void renderFrame(
|
||||||
|
StackFrame frame, AnsiStringBuilder out, String leftMargin, boolean forExpressionInput) {
|
||||||
var transformed = frameTransformer.apply(frame);
|
var transformed = frameTransformer.apply(frame);
|
||||||
renderSourceLine(transformed, out, leftMargin);
|
renderSourceLine(transformed, out, leftMargin, forExpressionInput);
|
||||||
renderSourceLocation(transformed, out, leftMargin);
|
renderSourceLocation(transformed, out, leftMargin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,14 +118,21 @@ public final class StackTraceRenderer {
|
|||||||
out.append('\n');
|
out.append('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderSourceLine(StackFrame frame, AnsiStringBuilder out, String leftMargin) {
|
private void renderSourceLine(
|
||||||
|
StackFrame frame, AnsiStringBuilder out, String leftMargin, boolean forExpressionInput) {
|
||||||
var originalSourceLine = frame.getSourceLines().get(0);
|
var originalSourceLine = frame.getSourceLines().get(0);
|
||||||
var leadingWhitespace = VmUtils.countLeadingWhitespace(originalSourceLine);
|
var leadingWhitespace = VmUtils.countLeadingWhitespace(originalSourceLine);
|
||||||
var sourceLine = originalSourceLine.strip();
|
var sourceLine = originalSourceLine.strip();
|
||||||
var startColumn = frame.getStartColumn() - leadingWhitespace;
|
var hasPreamble = false;
|
||||||
|
if (forExpressionInput && sourceLine.startsWith(VmUtils.EXPRESSION_PREAMBLE)) {
|
||||||
|
sourceLine = sourceLine.substring(PREAMBLE_LENGTH);
|
||||||
|
hasPreamble = true;
|
||||||
|
}
|
||||||
|
var preambleOffset = hasPreamble ? PREAMBLE_LENGTH : 0;
|
||||||
|
var startColumn = frame.getStartColumn() - leadingWhitespace - preambleOffset;
|
||||||
var endColumn =
|
var endColumn =
|
||||||
frame.getStartLine() == frame.getEndLine()
|
frame.getStartLine() == frame.getEndLine()
|
||||||
? frame.getEndColumn() - leadingWhitespace
|
? frame.getEndColumn() - leadingWhitespace - preambleOffset
|
||||||
: sourceLine.length();
|
: sourceLine.length();
|
||||||
|
|
||||||
var prefix = frame.getStartLine() + " | ";
|
var prefix = frame.getStartLine() + " | ";
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public abstract class VmException extends AbstractTruffleException {
|
|||||||
private final List<StackFrame> leadingStackFrames;
|
private final List<StackFrame> leadingStackFrames;
|
||||||
@Nullable private final BiConsumer<AnsiStringBuilder, Boolean> messageBuilder;
|
@Nullable private final BiConsumer<AnsiStringBuilder, Boolean> messageBuilder;
|
||||||
@Nullable protected BiConsumer<AnsiStringBuilder, Boolean> hintBuilder;
|
@Nullable protected BiConsumer<AnsiStringBuilder, Boolean> hintBuilder;
|
||||||
|
private boolean forExpressionInput;
|
||||||
|
|
||||||
public VmException(
|
public VmException(
|
||||||
@Nullable String message,
|
@Nullable String message,
|
||||||
@@ -62,6 +63,7 @@ public abstract class VmException extends AbstractTruffleException {
|
|||||||
this.insertedStackFrames = insertedStackFrames;
|
this.insertedStackFrames = insertedStackFrames;
|
||||||
this.leadingStackFrames = leadingStackFrames;
|
this.leadingStackFrames = leadingStackFrames;
|
||||||
this.hintBuilder = hintBuilder;
|
this.hintBuilder = hintBuilder;
|
||||||
|
this.forExpressionInput = forExpressionInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isExternalMessage() {
|
public final boolean isExternalMessage() {
|
||||||
@@ -112,6 +114,14 @@ public abstract class VmException extends AbstractTruffleException {
|
|||||||
this.hintBuilder = ((builder, aBoolean) -> builder.append(hint));
|
this.hintBuilder = ((builder, aBoolean) -> builder.append(hint));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setForExpressionInput(boolean forExpressionInput) {
|
||||||
|
this.forExpressionInput = forExpressionInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isForExpressionInput() {
|
||||||
|
return forExpressionInput;
|
||||||
|
}
|
||||||
|
|
||||||
public enum Kind {
|
public enum Kind {
|
||||||
EVAL_ERROR,
|
EVAL_ERROR,
|
||||||
UNDEFINED_VALUE,
|
UNDEFINED_VALUE,
|
||||||
|
|||||||
@@ -144,7 +144,8 @@ public final class VmExceptionRenderer {
|
|||||||
|
|
||||||
var hintBuilder = exception.getHintBuilder();
|
var hintBuilder = exception.getHintBuilder();
|
||||||
if (!frames.isEmpty()) {
|
if (!frames.isEmpty()) {
|
||||||
stackTraceRenderer.render(frames, hint, hintBuilder, out.append('\n'));
|
stackTraceRenderer.render(
|
||||||
|
frames, hint, hintBuilder, out.append('\n'), exception.isForExpressionInput());
|
||||||
} else if (hint != null) {
|
} else if (hint != null) {
|
||||||
// render hint if there are no stack frames
|
// render hint if there are no stack frames
|
||||||
out.append('\n').append(AnsiTheme.ERROR_MESSAGE_HINT, hint);
|
out.append('\n').append(AnsiTheme.ERROR_MESSAGE_HINT, hint);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import org.pkl.parser.syntax.Module;
|
|||||||
@TruffleLanguage.Registration(
|
@TruffleLanguage.Registration(
|
||||||
id = "pkl",
|
id = "pkl",
|
||||||
name = "Pkl",
|
name = "Pkl",
|
||||||
version = "0.32.0-dev",
|
version = "0.32.2",
|
||||||
characterMimeTypes = VmLanguage.MIME_TYPE,
|
characterMimeTypes = VmLanguage.MIME_TYPE,
|
||||||
contextPolicy = ContextPolicy.SHARED)
|
contextPolicy = ContextPolicy.SHARED)
|
||||||
@ProvidedTags(PklTags.Expression.class)
|
@ProvidedTags(PklTags.Expression.class)
|
||||||
|
|||||||
@@ -61,9 +61,12 @@ import org.pkl.core.module.ModuleKey;
|
|||||||
import org.pkl.core.module.ModuleKeys;
|
import org.pkl.core.module.ModuleKeys;
|
||||||
import org.pkl.core.module.ResolvedModuleKey;
|
import org.pkl.core.module.ResolvedModuleKey;
|
||||||
import org.pkl.core.util.EconomicMaps;
|
import org.pkl.core.util.EconomicMaps;
|
||||||
|
import org.pkl.core.util.Pair;
|
||||||
import org.pkl.parser.Parser;
|
import org.pkl.parser.Parser;
|
||||||
import org.pkl.parser.ParserError;
|
import org.pkl.parser.ParserError;
|
||||||
import org.pkl.parser.syntax.Expr;
|
import org.pkl.parser.syntax.Expr;
|
||||||
|
import org.pkl.parser.syntax.ImportClause;
|
||||||
|
import org.pkl.parser.syntax.ModuleDecl;
|
||||||
|
|
||||||
public final class VmUtils {
|
public final class VmUtils {
|
||||||
/** See {@link VmUtils#shouldRunTypeCheck(VirtualFrame)}. */
|
/** See {@link VmUtils#shouldRunTypeCheck(VirtualFrame)}. */
|
||||||
@@ -92,6 +95,10 @@ public final class VmUtils {
|
|||||||
private static final DecimalFormatSymbols ROOT_DECIMAL_FORMAT_SYMBOLS =
|
private static final DecimalFormatSymbols ROOT_DECIMAL_FORMAT_SYMBOLS =
|
||||||
DecimalFormatSymbols.getInstance(Locale.ROOT);
|
DecimalFormatSymbols.getInstance(Locale.ROOT);
|
||||||
|
|
||||||
|
public static final String EXPRESSION_PREAMBLE = "`THE REPL TEXT EXPR` = ";
|
||||||
|
|
||||||
|
private static final Parser parser = new Parser();
|
||||||
|
|
||||||
private VmUtils() {}
|
private VmUtils() {}
|
||||||
|
|
||||||
static VmTyped createEmptyModule() {
|
static VmTyped createEmptyModule() {
|
||||||
@@ -930,12 +937,69 @@ public final class VmUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a fake module that declares all the local properties that exist in {@code module}, so
|
||||||
|
* that AstBuilder can correctly resolve variables.
|
||||||
|
*
|
||||||
|
* <p>Additionally, return a {@link org.pkl.parser.syntax.Node} with its span calculated in terms
|
||||||
|
* of this fake module.
|
||||||
|
*
|
||||||
|
* <p>This created module is never executed.
|
||||||
|
*/
|
||||||
|
public static Pair<String, org.pkl.parser.syntax.Node> buildSyntheticModuleText(
|
||||||
|
org.pkl.parser.syntax.Node syntaxNode, VmTyped module, String srcText) {
|
||||||
|
if (syntaxNode instanceof ModuleDecl) {
|
||||||
|
return Pair.of(srcText, syntaxNode);
|
||||||
|
}
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
var nodeText = syntaxNode.text(srcText.toCharArray());
|
||||||
|
var adjustedNode = syntaxNode;
|
||||||
|
if (syntaxNode instanceof Expr) {
|
||||||
|
sb.append(EXPRESSION_PREAMBLE).append(nodeText).append('\n');
|
||||||
|
} else {
|
||||||
|
sb.append(nodeText).append('\n');
|
||||||
|
}
|
||||||
|
var mod = parser.parseModule(sb.toString());
|
||||||
|
if (syntaxNode instanceof Expr) {
|
||||||
|
adjustedNode = mod.getProperties().get(0).getExpr();
|
||||||
|
} else if (syntaxNode instanceof ImportClause) {
|
||||||
|
adjustedNode = mod.getImports().get(0);
|
||||||
|
} else if (syntaxNode instanceof org.pkl.parser.syntax.ClassProperty) {
|
||||||
|
adjustedNode = mod.getProperties().get(0);
|
||||||
|
} else if (syntaxNode instanceof org.pkl.parser.syntax.Class) {
|
||||||
|
adjustedNode = mod.getClasses().get(0);
|
||||||
|
} else if (syntaxNode instanceof org.pkl.parser.syntax.TypeAlias) {
|
||||||
|
adjustedNode = mod.getTypeAliases().get(0);
|
||||||
|
} else if (syntaxNode instanceof org.pkl.parser.syntax.ClassMethod) {
|
||||||
|
adjustedNode = mod.getMethods().get(0);
|
||||||
|
}
|
||||||
|
var cursor = EconomicMaps.getEntries(module.getMembers());
|
||||||
|
while (cursor.advance()) {
|
||||||
|
var key = cursor.getKey();
|
||||||
|
var value = cursor.getValue();
|
||||||
|
if (value.isLocal()) {
|
||||||
|
sb.append("local ").append(key).append(" = Undefined()\n\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert adjustedNode != null;
|
||||||
|
return Pair.of(sb.toString(), adjustedNode);
|
||||||
|
}
|
||||||
|
|
||||||
public static Object evaluateExpression(
|
public static Object evaluateExpression(
|
||||||
VmTyped module,
|
VmTyped module,
|
||||||
String expression,
|
String expression,
|
||||||
SecurityManager securityManager,
|
SecurityManager securityManager,
|
||||||
ModuleResolver moduleResolver) {
|
ModuleResolver moduleResolver) {
|
||||||
var syntheticModule = ModuleKeys.synthetic(REPL_TEXT_URI, expression);
|
org.pkl.parser.syntax.Node node;
|
||||||
|
try {
|
||||||
|
node = parser.parseExpressionInput(expression);
|
||||||
|
} catch (ParserError e) {
|
||||||
|
throw toVmException(e, expression, REPL_TEXT_URI, "");
|
||||||
|
}
|
||||||
|
var pair = buildSyntheticModuleText(node, module, expression);
|
||||||
|
var syntheticModuleText = pair.first;
|
||||||
|
var adjustedNode = pair.second;
|
||||||
|
var syntheticModule = ModuleKeys.synthetic(REPL_TEXT_URI, syntheticModuleText);
|
||||||
ResolvedModuleKey resolvedModule;
|
ResolvedModuleKey resolvedModule;
|
||||||
try {
|
try {
|
||||||
resolvedModule = syntheticModule.resolve(securityManager);
|
resolvedModule = syntheticModule.resolve(securityManager);
|
||||||
@@ -955,9 +1019,10 @@ public final class VmUtils {
|
|||||||
resolvedModule,
|
resolvedModule,
|
||||||
false);
|
false);
|
||||||
var language = VmLanguage.get(null);
|
var language = VmLanguage.get(null);
|
||||||
var parsedExpression = parseExpressionNode(expression, source);
|
|
||||||
var builder = new AstBuilder(source, language, moduleInfo, moduleResolver);
|
var builder = new AstBuilder(source, language, moduleInfo, moduleResolver);
|
||||||
var exprNode = builder.visitExpr(parsedExpression);
|
var mod = parser.parseModule(syntheticModuleText);
|
||||||
|
builder.visitModule(mod);
|
||||||
|
var exprNode = builder.visitExpr((Expr) adjustedNode);
|
||||||
var rootNode =
|
var rootNode =
|
||||||
new SimpleRootNode(
|
new SimpleRootNode(
|
||||||
language,
|
language,
|
||||||
@@ -966,7 +1031,12 @@ public final class VmUtils {
|
|||||||
"",
|
"",
|
||||||
exprNode);
|
exprNode);
|
||||||
var callNode = Truffle.getRuntime().createIndirectCallNode();
|
var callNode = Truffle.getRuntime().createIndirectCallNode();
|
||||||
return callNode.call(rootNode.getCallTarget(), module, module);
|
try {
|
||||||
|
return callNode.call(rootNode.getCallTarget(), module, module);
|
||||||
|
} catch (VmException e) {
|
||||||
|
e.setForExpressionInput(true);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int findCustomThisSlot(VirtualFrame frame) {
|
public static int findCustomThisSlot(VirtualFrame frame) {
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
// make sure that we don't trim this identifier when not using the expression evaluator
|
||||||
|
// see VmUtils.buildSyntheticModuleText()
|
||||||
|
`THE REPL TEXT EXPR` = throw("uh oh")
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
foo = new Mapping {
|
||||||
|
default { key ->
|
||||||
|
for (idx, char in key.split("")) {
|
||||||
|
["\(char)_\(idx)"] = "hi"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
["zzz"] {}
|
||||||
|
}
|
||||||
|
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
foo = new Mapping {
|
||||||
|
default { key ->
|
||||||
|
when (key is String) {
|
||||||
|
bar = key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
["x"] {}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
–– Pkl Error ––
|
||||||
|
uh oh
|
||||||
|
|
||||||
|
x | `THE REPL TEXT EXPR` = throw("uh oh")
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
at replTextPreamble#`THE REPL TEXT EXPR` (file:///$snippetsDir/input/errors/replTextPreamble.pkl)
|
||||||
|
|
||||||
|
xxx | renderer.renderDocument(value)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
at pkl.base#Module.output.text (pkl:base)
|
||||||
|
|
||||||
|
xxx | if (renderer is BytesRenderer) renderer.renderDocument(value) else text.encodeToBytes("UTF-8")
|
||||||
|
^^^^
|
||||||
|
at pkl.base#Module.output.bytes (pkl:base)
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
foo {
|
||||||
|
["zzz"] {
|
||||||
|
["z_0"] = "hi"
|
||||||
|
["z_1"] = "hi"
|
||||||
|
["z_2"] = "hi"
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
foo {
|
||||||
|
["x"] {
|
||||||
|
bar = "x"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -134,4 +134,77 @@ class EvaluateExpressionTest {
|
|||||||
|
|
||||||
assertThat(error).hasMessageContaining("Expected value of type `String`, but got type `Int`")
|
assertThat(error).hasMessageContaining("Expected value of type `String`, but got type `Int`")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `evaluate local property`() {
|
||||||
|
val result = evaluate("local foo = 1", "foo")
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo(1L)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `evaluate throwing local property trims expression preamble when rendering stack frames`() {
|
||||||
|
val error = assertThrows<PklException> { evaluate("local foo = throw(\"uh oh\")", "foo") }
|
||||||
|
|
||||||
|
assertThat(error.message)
|
||||||
|
.isEqualTo(
|
||||||
|
"""
|
||||||
|
–– Pkl Error ––
|
||||||
|
uh oh
|
||||||
|
|
||||||
|
1 | local foo = throw("uh oh")
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
at text#foo (repl:text)
|
||||||
|
|
||||||
|
1 | foo
|
||||||
|
^^^
|
||||||
|
at (repl:text)
|
||||||
|
|
||||||
|
"""
|
||||||
|
.trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `evaluate throwing multi-line expression renders without crashing`() {
|
||||||
|
val error =
|
||||||
|
assertThrows<PklException> {
|
||||||
|
evaluate(
|
||||||
|
"x = 1",
|
||||||
|
"""
|
||||||
|
let (_a = 1)
|
||||||
|
let (_b = 2)
|
||||||
|
throw("boom")
|
||||||
|
"""
|
||||||
|
.trimIndent(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat(error.message)
|
||||||
|
.isEqualTo(
|
||||||
|
"""
|
||||||
|
–– Pkl Error ––
|
||||||
|
boom
|
||||||
|
|
||||||
|
3 | throw("boom")
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
at (repl:text)
|
||||||
|
|
||||||
|
1 | let (_a = 1)
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
at repl:text.<let expr> (repl:text)
|
||||||
|
|
||||||
|
"""
|
||||||
|
.trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `evaluate import`() {
|
||||||
|
val result = evaluate("import \"pkl:base\"", "base")
|
||||||
|
|
||||||
|
assertThat(result).isInstanceOf(PModule::class.java)
|
||||||
|
result as PModule
|
||||||
|
assertThat(result.moduleName).isEqualTo("pkl.base")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.pkl.core.http
|
package org.pkl.core.http
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.io.InputStream
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.net.http.HttpClient as JdkHttpClient
|
import java.net.http.HttpClient as JdkHttpClient
|
||||||
import java.net.http.HttpRequest
|
import java.net.http.HttpRequest
|
||||||
@@ -25,6 +27,7 @@ import java.util.Locale
|
|||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.assertj.core.api.Assertions.assertThatList
|
import org.assertj.core.api.Assertions.assertThatList
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.pkl.commons.test.FakeHttpResponse
|
||||||
import org.pkl.core.util.GlobResolver
|
import org.pkl.core.util.GlobResolver
|
||||||
import org.pkl.core.util.IoUtils
|
import org.pkl.core.util.IoUtils
|
||||||
|
|
||||||
@@ -441,4 +444,38 @@ class RequestRewritingClientTest {
|
|||||||
assertThatList(captured.request.headers().allValues("user-agent"))
|
assertThatList(captured.request.headers().allValues("user-agent"))
|
||||||
.containsExactly("My User Agent")
|
.containsExactly("My User Agent")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `closes intermediate redirect response body before following the redirect`() {
|
||||||
|
val intermediateBody = CloseTrackingInputStream()
|
||||||
|
val delegate =
|
||||||
|
ReplayingClient(
|
||||||
|
FakeHttpResponse<InputStream>().apply {
|
||||||
|
statusCode = 302
|
||||||
|
headers = httpHeaders("Location", "/bar.pkl")
|
||||||
|
body = intermediateBody
|
||||||
|
},
|
||||||
|
FakeHttpResponse<InputStream>(),
|
||||||
|
)
|
||||||
|
val client =
|
||||||
|
RequestRewritingClient("Pkl", Duration.ofSeconds(42), -1, delegate, mapOf(), mapOf())
|
||||||
|
val request = HttpRequest.newBuilder(URI("https://example.com/foo.pkl")).build()
|
||||||
|
|
||||||
|
client.send(request, BodyHandlers.ofInputStream(), NoopChecker)
|
||||||
|
|
||||||
|
assertThat(intermediateBody.closed)
|
||||||
|
.`as`("intermediate 3xx response body must be closed to release its connection")
|
||||||
|
.isTrue
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ByteArrayInputStream that records whether it was closed. */
|
||||||
|
private class CloseTrackingInputStream : ByteArrayInputStream(ByteArray(0)) {
|
||||||
|
var closed = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
closed = true
|
||||||
|
super.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,6 +16,9 @@
|
|||||||
package org.pkl.core.http
|
package org.pkl.core.http
|
||||||
|
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
import java.net.http.HttpHeaders
|
||||||
|
import java.net.http.HttpRequest
|
||||||
|
import java.net.http.HttpResponse
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
data class HttpSettings(
|
data class HttpSettings(
|
||||||
@@ -32,3 +35,21 @@ fun HttpClient.getConfiguredSettings(): HttpSettings {
|
|||||||
object NoopChecker : HttpClient.HttpRequestChecker {
|
object NoopChecker : HttpClient.HttpRequestChecker {
|
||||||
override fun check(uri: URI) {}
|
override fun check(uri: URI) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun httpHeaders(name: String, value: String): HttpHeaders =
|
||||||
|
HttpHeaders.of(mapOf(name to listOf(value))) { _, _ -> true }
|
||||||
|
|
||||||
|
class ReplayingClient(vararg responses: HttpResponse<*>) : HttpClient {
|
||||||
|
private val responses = ArrayDeque(responses.toList())
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
override fun <T : Any> send(
|
||||||
|
request: HttpRequest,
|
||||||
|
responseBodyHandler: HttpResponse.BodyHandler<T>,
|
||||||
|
httpRequestChecker: HttpClient.HttpRequestChecker,
|
||||||
|
): HttpResponse<T> {
|
||||||
|
return responses.removeFirst() as HttpResponse<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun close() {}
|
||||||
|
}
|
||||||
@@ -192,7 +192,7 @@ class StackTraceRendererTest {
|
|||||||
val loop = StackTraceRenderer.StackFrameLoop(loopFrames, 1)
|
val loop = StackTraceRenderer.StackFrameLoop(loopFrames, 1)
|
||||||
val frames = listOf(createFrame("bar", 1), createFrame("baz", 2), loop)
|
val frames = listOf(createFrame("bar", 1), createFrame("baz", 2), loop)
|
||||||
val formatter = AnsiStringBuilder(false)
|
val formatter = AnsiStringBuilder(false)
|
||||||
renderer.doRender(frames, null, null, formatter, "", true)
|
renderer.doRender(frames, null, null, formatter, "", true, true)
|
||||||
val renderedFrames = formatter.toString()
|
val renderedFrames = formatter.toString()
|
||||||
assertThat(renderedFrames)
|
assertThat(renderedFrames)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ tasks.test {
|
|||||||
inputs.dir("src/test/files/SinglePackageTest/output")
|
inputs.dir("src/test/files/SinglePackageTest/output")
|
||||||
}
|
}
|
||||||
|
|
||||||
val testNativeExecutable by
|
val testNativeExecutable =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testNativeExecutable") {
|
||||||
dependsOn(tasks.assembleNative)
|
dependsOn(tasks.assembleNative)
|
||||||
testClassesDirs = sourceSets.test.get().output.classesDirs
|
testClassesDirs = sourceSets.test.get().output.classesDirs
|
||||||
classpath = sourceSets.test.get().runtimeClasspath
|
classpath = sourceSets.test.get().runtimeClasspath
|
||||||
@@ -91,8 +91,8 @@ val testNativeExecutable by
|
|||||||
filter { includeTestsMatching("org.pkl.doc.NativeExecutableTest") }
|
filter { includeTestsMatching("org.pkl.doc.NativeExecutableTest") }
|
||||||
}
|
}
|
||||||
|
|
||||||
val testJavaExecutable by
|
val testJavaExecutable =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testJavaExecutable") {
|
||||||
testClassesDirs = sourceSets.test.get().output.classesDirs
|
testClassesDirs = sourceSets.test.get().output.classesDirs
|
||||||
classpath = sourceSets.test.get().runtimeClasspath
|
classpath = sourceSets.test.get().runtimeClasspath
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ plugins {
|
|||||||
id("pklJSpecify")
|
id("pklJSpecify")
|
||||||
}
|
}
|
||||||
|
|
||||||
val pklDistributionCurrent: Configuration by configurations.creating
|
val pklDistributionCurrent: Configuration = configurations.create("pklDistributionCurrent")
|
||||||
val pklHistoricalDistributions: Configuration by configurations.creating
|
val pklHistoricalDistributions: Configuration = configurations.create("pklHistoricalDistributions")
|
||||||
|
|
||||||
// Because pkl-executor doesn't depend on other Pkl modules
|
// Because pkl-executor doesn't depend on other Pkl modules
|
||||||
// (nor has overlapping dependencies that could cause a version conflict),
|
// (nor has overlapping dependencies that could cause a version conflict),
|
||||||
@@ -66,37 +66,39 @@ publishing {
|
|||||||
|
|
||||||
sourceSets { main { java { srcDir("src/main/java") } } }
|
sourceSets { main { java { srcDir("src/main/java") } } }
|
||||||
|
|
||||||
val prepareHistoricalDistributions by tasks.registering {
|
val prepareHistoricalDistributions =
|
||||||
val outputDir = layout.buildDirectory.dir("pklHistoricalDistributions")
|
tasks.register("prepareHistoricalDistributions") {
|
||||||
inputs.files(pklHistoricalDistributions.files)
|
val outputDir = layout.buildDirectory.dir("pklHistoricalDistributions")
|
||||||
outputs.dir(outputDir)
|
inputs.files(pklHistoricalDistributions.files)
|
||||||
doLast {
|
outputs.dir(outputDir)
|
||||||
val distributionDir = outputDir.get().asFile.toPath().also(Files::createDirectories)
|
doLast {
|
||||||
for (file in pklHistoricalDistributions.files) {
|
val distributionDir = outputDir.get().asFile.toPath().also(Files::createDirectories)
|
||||||
val target = distributionDir.resolve(file.name)
|
for (file in pklHistoricalDistributions.files) {
|
||||||
// Create normal files on Windows, symlink on macOS/linux (need admin privileges to create
|
val target = distributionDir.resolve(file.name)
|
||||||
// symlinks on Windows)
|
// Create normal files on Windows, symlink on macOS/linux (need admin privileges to create
|
||||||
if (buildInfo.os.isWindows) {
|
// symlinks on Windows)
|
||||||
if (!Files.isRegularFile(target, LinkOption.NOFOLLOW_LINKS)) {
|
if (buildInfo.os.isWindows) {
|
||||||
if (Files.exists(target)) {
|
if (!Files.isRegularFile(target, LinkOption.NOFOLLOW_LINKS)) {
|
||||||
Files.delete(target)
|
if (Files.exists(target)) {
|
||||||
|
Files.delete(target)
|
||||||
|
}
|
||||||
|
Files.copy(file.toPath(), target)
|
||||||
}
|
}
|
||||||
Files.copy(file.toPath(), target)
|
} else {
|
||||||
}
|
if (!Files.isSymbolicLink(target)) {
|
||||||
} else {
|
if (Files.exists(target)) {
|
||||||
if (!Files.isSymbolicLink(target)) {
|
Files.delete(target)
|
||||||
if (Files.exists(target)) {
|
}
|
||||||
Files.delete(target)
|
Files.createSymbolicLink(target, file.toPath())
|
||||||
}
|
}
|
||||||
Files.createSymbolicLink(target, file.toPath())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val prepareTest by tasks.registering {
|
val prepareTest =
|
||||||
dependsOn(pklDistributionCurrent, prepareHistoricalDistributions)
|
tasks.register("prepareTest") {
|
||||||
}
|
dependsOn(pklDistributionCurrent, prepareHistoricalDistributions)
|
||||||
|
}
|
||||||
|
|
||||||
tasks.test { dependsOn(prepareTest) }
|
tasks.test { dependsOn(prepareTest) }
|
||||||
@@ -69,12 +69,12 @@ sourceSets {
|
|||||||
// Then the path to the jar file and the toolchain's `java` binary
|
// Then the path to the jar file and the toolchain's `java` binary
|
||||||
// are injected into tests as properties.
|
// are injected into tests as properties.
|
||||||
|
|
||||||
val externalReader by sourceSets.creating {}
|
val externalReader = sourceSets.create("externalReader") {}
|
||||||
|
|
||||||
dependencies { "externalReaderImplementation"(libs.msgpack) }
|
dependencies { "externalReaderImplementation"(libs.msgpack) }
|
||||||
|
|
||||||
val externalReaderJar by
|
val externalReaderJar =
|
||||||
tasks.registering(Jar::class) {
|
tasks.register<Jar>("externalReaderJar") {
|
||||||
description = "Builds an external reader executable jar file"
|
description = "Builds an external reader executable jar file"
|
||||||
archiveBaseName = "external-reader"
|
archiveBaseName = "external-reader"
|
||||||
archiveVersion = ""
|
archiveVersion = ""
|
||||||
|
|||||||
@@ -36,38 +36,38 @@ private fun Test.configureNativeTest() {
|
|||||||
include("**/NativeServerTest.*")
|
include("**/NativeServerTest.*")
|
||||||
}
|
}
|
||||||
|
|
||||||
val testMacExecutableAarch64 by
|
val testMacExecutableAarch64 =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testMacExecutableAarch64") {
|
||||||
dependsOn(":pkl-cli:macExecutableAarch64")
|
dependsOn(":pkl-cli:macExecutableAarch64")
|
||||||
configureNativeTest()
|
configureNativeTest()
|
||||||
}
|
}
|
||||||
|
|
||||||
val testMacExecutableAmd64 by
|
val testMacExecutableAmd64 =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testMacExecutableAmd64") {
|
||||||
dependsOn(":pkl-cli:macExecutableAmd64")
|
dependsOn(":pkl-cli:macExecutableAmd64")
|
||||||
configureNativeTest()
|
configureNativeTest()
|
||||||
}
|
}
|
||||||
|
|
||||||
val testLinuxExecutableAmd64 by
|
val testLinuxExecutableAmd64 =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testLinuxExecutableAmd64") {
|
||||||
dependsOn(":pkl-cli:linuxExecutableAmd64")
|
dependsOn(":pkl-cli:linuxExecutableAmd64")
|
||||||
configureNativeTest()
|
configureNativeTest()
|
||||||
}
|
}
|
||||||
|
|
||||||
val testLinuxExecutableAarch64 by
|
val testLinuxExecutableAarch64 =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testLinuxExecutableAarch64") {
|
||||||
dependsOn(":pkl-cli:linuxExecutableAarch64")
|
dependsOn(":pkl-cli:linuxExecutableAarch64")
|
||||||
configureNativeTest()
|
configureNativeTest()
|
||||||
}
|
}
|
||||||
|
|
||||||
val testAlpineExecutableAmd64 by
|
val testAlpineExecutableAmd64 =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testAlpineExecutableAmd64") {
|
||||||
dependsOn(":pkl-cli:alpineExecutableAmd64")
|
dependsOn(":pkl-cli:alpineExecutableAmd64")
|
||||||
configureNativeTest()
|
configureNativeTest()
|
||||||
}
|
}
|
||||||
|
|
||||||
val testWindowsExecutableAmd64 by
|
val testWindowsExecutableAmd64 =
|
||||||
tasks.registering(Test::class) {
|
tasks.register<Test>("testWindowsExecutableAmd64") {
|
||||||
dependsOn(":pkl-cli:windowsExecutableAmd64")
|
dependsOn(":pkl-cli:windowsExecutableAmd64")
|
||||||
configureNativeTest()
|
configureNativeTest()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ plugins {
|
|||||||
signing
|
signing
|
||||||
}
|
}
|
||||||
|
|
||||||
val placeholder: SourceSet by sourceSets.creating
|
val placeholder = sourceSets.create("placeholder")
|
||||||
|
|
||||||
val firstPartySourcesJars by configurations.existing
|
val firstPartySourcesJars = configurations.named("firstPartySourcesJars")
|
||||||
|
|
||||||
// Note: pkl-tools cannot (easily) contain pkl-config-kotlin
|
// Note: pkl-tools cannot (easily) contain pkl-config-kotlin
|
||||||
// because pkl-tools ships with a shaded Kotlin stdlib.
|
// because pkl-tools ships with a shaded Kotlin stdlib.
|
||||||
@@ -55,12 +55,13 @@ dependencies {
|
|||||||
|
|
||||||
// TODO: need to figure out how to properly generate javadoc here.
|
// TODO: need to figure out how to properly generate javadoc here.
|
||||||
// For now, we'll include a placeholder javadoc jar.
|
// For now, we'll include a placeholder javadoc jar.
|
||||||
val javadocPlaceholder by tasks.registering(Javadoc::class) { source = placeholder.allJava }
|
val javadocPlaceholder =
|
||||||
|
tasks.register<Javadoc>("javadocPlaceholder") { source = placeholder.allJava }
|
||||||
|
|
||||||
java { withJavadocJar() }
|
java { withJavadocJar() }
|
||||||
|
|
||||||
val javadocJar by
|
val javadocJar =
|
||||||
tasks.existing(Jar::class) {
|
tasks.named<Jar>("javadocJar") {
|
||||||
from(javadocPlaceholder)
|
from(javadocPlaceholder)
|
||||||
archiveBaseName.set("pkl-tools-all")
|
archiveBaseName.set("pkl-tools-all")
|
||||||
archiveClassifier.set("javadoc")
|
archiveClassifier.set("javadoc")
|
||||||
@@ -105,8 +106,8 @@ private fun Exec.configureTestStartFatJar(launcher: Provider<JavaLauncher>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val testStartFatJar by
|
val testStartFatJar =
|
||||||
tasks.registering(Exec::class) { configureTestStartFatJar(buildInfo.javaTestLauncher) }
|
tasks.register<Exec>("testStartFatJar") { configureTestStartFatJar(buildInfo.javaTestLauncher) }
|
||||||
|
|
||||||
tasks.validateFatJar { dependsOn(testStartFatJar) }
|
tasks.validateFatJar { dependsOn(testStartFatJar) }
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
///
|
///
|
||||||
/// Warning: Although this module is ready for initial use,
|
/// Warning: Although this module is ready for initial use,
|
||||||
/// benchmark results may be inaccurate or inconsistent.
|
/// benchmark results may be inaccurate or inconsistent.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.Benchmark
|
module pkl.Benchmark
|
||||||
|
|
||||||
import "pkl:platform" as _platform
|
import "pkl:platform" as _platform
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@
|
|||||||
/// // ...
|
/// // ...
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
open module pkl.Command
|
open module pkl.Command
|
||||||
|
|
||||||
import "pkl:Command"
|
import "pkl:Command"
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
/// @Deprecated { message = "Use `com.example.Birds.Parrot` instead" }
|
/// @Deprecated { message = "Use `com.example.Birds.Parrot` instead" }
|
||||||
/// amends "pkl:PackageInfo"
|
/// amends "pkl:PackageInfo"
|
||||||
/// ```
|
/// ```
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.DocPackageInfo
|
module pkl.DocPackageInfo
|
||||||
|
|
||||||
// used by doc comments
|
// used by doc comments
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
///
|
///
|
||||||
/// title = "Title displayed in the header of each page"
|
/// title = "Title displayed in the header of each page"
|
||||||
/// ```
|
/// ```
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.DocsiteInfo
|
module pkl.DocsiteInfo
|
||||||
|
|
||||||
import "pkl:reflect"
|
import "pkl:reflect"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// Common settings for Pkl's own evaluator.
|
/// Common settings for Pkl's own evaluator.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
@Since { version = "0.26.0" }
|
@Since { version = "0.26.0" }
|
||||||
module pkl.EvaluatorSettings
|
module pkl.EvaluatorSettings
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -64,7 +64,7 @@
|
|||||||
/// value = project
|
/// value = project
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.Project
|
module pkl.Project
|
||||||
|
|
||||||
import "pkl:EvaluatorSettings" as EvaluatorSettingsModule
|
import "pkl:EvaluatorSettings" as EvaluatorSettingsModule
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@
|
|||||||
/// These tools differentiate from [pkl:reflect][reflect] in that they parse Pkl modules, but do not
|
/// These tools differentiate from [pkl:reflect][reflect] in that they parse Pkl modules, but do not
|
||||||
/// execute any code within these modules.
|
/// execute any code within these modules.
|
||||||
@Since { version = "0.27.0" }
|
@Since { version = "0.27.0" }
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.analyze
|
module pkl.analyze
|
||||||
|
|
||||||
// used by doc comments
|
// used by doc comments
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@
|
|||||||
/// Fundamental properties, methods, and classes for writing Pkl programs.
|
/// Fundamental properties, methods, and classes for writing Pkl programs.
|
||||||
///
|
///
|
||||||
/// Members of this module are automatically available in every Pkl module.
|
/// Members of this module are automatically available in every Pkl module.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.base
|
module pkl.base
|
||||||
|
|
||||||
import "pkl:json"
|
import "pkl:json"
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// A JSON parser.
|
/// A JSON parser.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.json
|
module pkl.json
|
||||||
|
|
||||||
/// Annotate properties of classes and modules with this class to override how a [JsonRenderer]
|
/// Annotate properties of classes and modules with this class to override how a [JsonRenderer]
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// A [Jsonnet](https://jsonnet.org) renderer.
|
/// A [Jsonnet](https://jsonnet.org) renderer.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.jsonnet
|
module pkl.jsonnet
|
||||||
|
|
||||||
/// Constructs an [ImportStr].
|
/// Constructs an [ImportStr].
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
///
|
///
|
||||||
/// Note that some mathematical functions, such as `sign()`, `abs()`, and `round()`,
|
/// Note that some mathematical functions, such as `sign()`, `abs()`, and `round()`,
|
||||||
/// are directly defined in classes [Number], [Int], and [Float].
|
/// are directly defined in classes [Number], [Int], and [Float].
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.math
|
module pkl.math
|
||||||
|
|
||||||
/// The minimum [Int] value: `-9223372036854775808`.
|
/// The minimum [Int] value: `-9223372036854775808`.
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
/// The `pkl-binary` format uses MessagePack encoding.
|
/// The `pkl-binary` format uses MessagePack encoding.
|
||||||
/// Its specification is available at
|
/// Its specification is available at
|
||||||
/// <https://pkl-lang.org/main/current/bindings-specification/binary-encoding.html>.
|
/// <https://pkl-lang.org/main/current/bindings-specification/binary-encoding.html>.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.pklbinary
|
module pkl.pklbinary
|
||||||
|
|
||||||
/// Render values as `pkl-binary`.
|
/// Render values as `pkl-binary`.
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// Information about the platform that the current program runs on.
|
/// Information about the platform that the current program runs on.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.platform
|
module pkl.platform
|
||||||
|
|
||||||
/// The platform that the current program runs on.
|
/// The platform that the current program runs on.
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
/// A renderer for [Protocol Buffers](https://developers.google.com/protocol-buffers).
|
/// A renderer for [Protocol Buffers](https://developers.google.com/protocol-buffers).
|
||||||
/// Note: This module is _experimental_ and not ready for production use.
|
/// Note: This module is _experimental_ and not ready for production use.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.protobuf
|
module pkl.protobuf
|
||||||
|
|
||||||
import "pkl:reflect"
|
import "pkl:reflect"
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@
|
|||||||
/// * Workflow tools
|
/// * Workflow tools
|
||||||
///
|
///
|
||||||
/// _**WARNING**_: This module is _experimental_ and not ready for production use.
|
/// _**WARNING**_: This module is _experimental_ and not ready for production use.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
@Since { version = "0.32.0" }
|
@Since { version = "0.32.0" }
|
||||||
module pkl.ref
|
module pkl.ref
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@
|
|||||||
/// - Documentation generators (such as *Pkldoc*)
|
/// - Documentation generators (such as *Pkldoc*)
|
||||||
/// - Code generators (such as *pkl-codegen-java* and *pkl-codegen-kotlin*)
|
/// - Code generators (such as *pkl-codegen-java* and *pkl-codegen-kotlin*)
|
||||||
/// - Domain-specific schema validators
|
/// - Domain-specific schema validators
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.reflect
|
module pkl.reflect
|
||||||
|
|
||||||
import "pkl:base"
|
import "pkl:base"
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// Information about the Pkl release that the current program runs on.
|
/// Information about the Pkl release that the current program runs on.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.release
|
module pkl.release
|
||||||
|
|
||||||
import "pkl:semver"
|
import "pkl:semver"
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// Parsing, comparison, and manipulation of [semantic version](https://semver.org/spec/v2.0.0.html) numbers.
|
/// Parsing, comparison, and manipulation of [semantic version](https://semver.org/spec/v2.0.0.html) numbers.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.semver
|
module pkl.semver
|
||||||
|
|
||||||
/// Tells whether [version] is a valid semantic version number.
|
/// Tells whether [version] is a valid semantic version number.
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@
|
|||||||
/// Every settings file must amend this module.
|
/// Every settings file must amend this module.
|
||||||
/// Unless CLI commands and build tool plugins are explicitly configured with a settings file,
|
/// Unless CLI commands and build tool plugins are explicitly configured with a settings file,
|
||||||
/// they will use `~/.pkl/settings.pkl` or the defaults specified in this module.
|
/// they will use `~/.pkl/settings.pkl` or the defaults specified in this module.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.settings
|
module pkl.settings
|
||||||
|
|
||||||
import "pkl:EvaluatorSettings"
|
import "pkl:EvaluatorSettings"
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// Utilities for generating shell scripts.
|
/// Utilities for generating shell scripts.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.shell
|
module pkl.shell
|
||||||
|
|
||||||
/// Escapes [str] by enclosing it in single quotes.
|
/// Escapes [str] by enclosing it in single quotes.
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ plugins {
|
|||||||
|
|
||||||
// create and publish a self-contained stdlib archive
|
// create and publish a self-contained stdlib archive
|
||||||
// purpose is to provide non-jvm tools/projects with a versioned stdlib
|
// purpose is to provide non-jvm tools/projects with a versioned stdlib
|
||||||
val stdlibZip by
|
val stdlibZip =
|
||||||
tasks.registering(Zip::class) {
|
tasks.register<Zip>("stdlibZip") {
|
||||||
destinationDirectory.set(layout.buildDirectory.dir("libs"))
|
destinationDirectory.set(layout.buildDirectory.dir("libs"))
|
||||||
archiveBaseName.set("pkl-stdlib")
|
archiveBaseName.set("pkl-stdlib")
|
||||||
archiveVersion.set(project.version as String)
|
archiveVersion.set(project.version as String)
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
///
|
///
|
||||||
/// To write tests, amend this module and define [facts] or [examples] (or both).
|
/// To write tests, amend this module and define [facts] or [examples] (or both).
|
||||||
/// To run tests, use the `pkl test` command to evaluate the amended module.
|
/// To run tests, use the `pkl test` command to evaluate the amended module.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
open module pkl.test
|
open module pkl.test
|
||||||
|
|
||||||
/// Named groups of boolean expressions that are expected to evaluate to [true].
|
/// Named groups of boolean expressions that are expected to evaluate to [true].
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// An XML renderer.
|
/// An XML renderer.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.xml
|
module pkl.xml
|
||||||
|
|
||||||
/// Renders values as XML.
|
/// Renders values as XML.
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// A YAML 1.2 compliant YAML parser.
|
/// A YAML 1.2 compliant YAML parser.
|
||||||
@ModuleInfo { minPklVersion = "0.32.0" }
|
@ModuleInfo { minPklVersion = "0.32.2" }
|
||||||
module pkl.yaml
|
module pkl.yaml
|
||||||
|
|
||||||
/// Annotate properties of classes and modules with this class to override how a [YamlRenderer]
|
/// Annotate properties of classes and modules with this class to override how a [YamlRenderer]
|
||||||
|
|||||||
Reference in new issue
Block a user