mirror of
https://github.com/apple/pkl.git
synced 2026-01-11 22:30:54 +01:00
Compare commits
263 Commits
0.26.2
...
release/0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a3722a471 | ||
|
|
2a7195125c | ||
|
|
f0896ba16f | ||
|
|
9f7997bbc4 | ||
|
|
245b53bc8a | ||
|
|
9a92d75fcb | ||
|
|
419127fb0d | ||
|
|
f7951510b9 | ||
|
|
1b49ec9422 | ||
|
|
bdabcea216 | ||
|
|
5f00f9c82e | ||
|
|
efee9f3801 | ||
|
|
8e88133248 | ||
|
|
b38b15ba71 | ||
|
|
1c4fbe7c1c | ||
|
|
ae046a804b | ||
|
|
53f6951d81 | ||
|
|
7c8c4438d5 | ||
|
|
bdf6aa6b60 | ||
|
|
03d8e01801 | ||
|
|
85e4f133a4 | ||
|
|
306a3b0fc2 | ||
|
|
fe064960b4 | ||
|
|
6cd73227a1 | ||
|
|
ba82c5c6d6 | ||
|
|
decb4ea66e | ||
|
|
99020bb79d | ||
|
|
fea031a138 | ||
|
|
48ad4386c8 | ||
|
|
3a35be6311 | ||
|
|
0973774a5d | ||
|
|
dbf57280ba | ||
|
|
f1388ffb2f | ||
|
|
d6fd7e0942 | ||
|
|
e9320557b7 | ||
|
|
3bd8a88506 | ||
|
|
0b0f3b131d | ||
|
|
568c6ccbc2 | ||
|
|
dd9800c70a | ||
|
|
2bc9c2f424 | ||
|
|
4eeb61dc74 | ||
|
|
7d50c46c29 | ||
|
|
a19e6bf684 | ||
|
|
021f43bec4 | ||
|
|
fe2e4aa1a4 | ||
|
|
948a20ad0c | ||
|
|
919d63e51a | ||
|
|
e4716c9e45 | ||
|
|
49a593f5c9 | ||
|
|
e98b42cffd | ||
|
|
38c44860d4 | ||
|
|
854074e619 | ||
|
|
3119e0781b | ||
|
|
b445713b8c | ||
|
|
aad530b9a8 | ||
|
|
1cd0549bd6 | ||
|
|
8b7d59e4e4 | ||
|
|
f7eaeddc78 | ||
|
|
18e7a7e87e | ||
|
|
bf484b3431 | ||
|
|
5636fb55c4 | ||
|
|
5021107269 | ||
|
|
3baefbcfd3 | ||
|
|
a0a64923a6 | ||
|
|
09166ba165 | ||
|
|
9ba7fa01af | ||
|
|
9f22c56ff5 | ||
|
|
06d04878f7 | ||
|
|
d3ba0f9e47 | ||
|
|
cc9827f032 | ||
|
|
d1f7b639a7 | ||
|
|
cf889246fd | ||
|
|
fcce5c7e11 | ||
|
|
52a86d3f32 | ||
|
|
31c80e792e | ||
|
|
50cfb1c962 | ||
|
|
643c6f5a76 | ||
|
|
227f0637fc | ||
|
|
baa34a6dd1 | ||
|
|
2ffd201172 | ||
|
|
ee23a8c3f4 | ||
|
|
28b128f86f | ||
|
|
d270829ed3 | ||
|
|
350b71a634 | ||
|
|
28df90527b | ||
|
|
eabfcdd333 | ||
|
|
1a4f9ee72e | ||
|
|
65cf3237b7 | ||
|
|
d00d0ba79f | ||
|
|
f56b1bb84f | ||
|
|
b526902bf0 | ||
|
|
7c3f8ad261 | ||
|
|
7ed710c226 | ||
|
|
ad99e4a7f7 | ||
|
|
e85e888f92 | ||
|
|
3b6fbdff15 | ||
|
|
9784cd7265 | ||
|
|
aadcccd0fc | ||
|
|
9075ca0729 | ||
|
|
5e12dfb200 | ||
|
|
408242a44c | ||
|
|
8cfd2357c6 | ||
|
|
3fa935b390 | ||
|
|
aa8a0f18e8 | ||
|
|
3815a0206b | ||
|
|
90df0662af | ||
|
|
11169d6691 | ||
|
|
5dc672731d | ||
|
|
258eda8630 | ||
|
|
cdd6d52642 | ||
|
|
29049ac437 | ||
|
|
2a9b10097d | ||
|
|
257bd6f699 | ||
|
|
75bd21420b | ||
|
|
273d1219a6 | ||
|
|
ec7d7267dc | ||
|
|
3096da1920 | ||
|
|
100dd0560e | ||
|
|
3296dd8a89 | ||
|
|
160e4a5636 | ||
|
|
267de3c789 | ||
|
|
f6c74e90a8 | ||
|
|
467e64f98e | ||
|
|
d9c65d484a | ||
|
|
a014e8d1d1 | ||
|
|
6fd82a5bb8 | ||
|
|
29fb99ffea | ||
|
|
efe1608bd6 | ||
|
|
6cab47067b | ||
|
|
17f431370a | ||
|
|
9982511513 | ||
|
|
6bd8e288ef | ||
|
|
01bf844a96 | ||
|
|
70aaa6322e | ||
|
|
1bc473ba54 | ||
|
|
ad06a96a8a | ||
|
|
1abd174d77 | ||
|
|
45302c8a00 | ||
|
|
e6c1e1411b | ||
|
|
cc579f8fd6 | ||
|
|
b93cb9b322 | ||
|
|
7c1604b264 | ||
|
|
0c6808566f | ||
|
|
51df2f3aa4 | ||
|
|
09bc09d058 | ||
|
|
16af6b7bcc | ||
|
|
2a7eec592d | ||
|
|
dda457aa8e | ||
|
|
696a325511 | ||
|
|
9a27616956 | ||
|
|
406fa4cf40 | ||
|
|
df38011c9e | ||
|
|
b8d90eddec | ||
|
|
9faff5e551 | ||
|
|
3f91824dc2 | ||
|
|
dddbb27143 | ||
|
|
3246a0e449 | ||
|
|
a22a8a8127 | ||
|
|
ff60f61cbb | ||
|
|
0d199892b8 | ||
|
|
a533e53838 | ||
|
|
44fd680e43 | ||
|
|
33bffbe158 | ||
|
|
7eedcf1e50 | ||
|
|
a85a173faa | ||
|
|
b402463f3c | ||
|
|
6d161ce1d4 | ||
|
|
40a08affa6 | ||
|
|
4b4d81ba93 | ||
|
|
9692504b5f | ||
|
|
fa25fb46fd | ||
|
|
3f38173ed5 | ||
|
|
d50179827d | ||
|
|
03462fefae | ||
|
|
e217cfcd6f | ||
|
|
66d751f093 | ||
|
|
1be1fe4863 | ||
|
|
cc72f9d160 | ||
|
|
a03827951c | ||
|
|
71db4d0fae | ||
|
|
dd16f7469e | ||
|
|
acd2222534 | ||
|
|
666f8c3939 | ||
|
|
466ae6fd4c | ||
|
|
08be6be059 | ||
|
|
8fa3acf32f | ||
|
|
8b0118fec5 | ||
|
|
93cc3253eb | ||
|
|
1ceb489d78 | ||
|
|
4b6bc7bb7c | ||
|
|
cbbcca0d84 | ||
|
|
22c9a6c9f4 | ||
|
|
069a5d1adc | ||
|
|
86d870ba09 | ||
|
|
2040f14b07 | ||
|
|
730257861f | ||
|
|
f9fe226eba | ||
|
|
5a654e453c | ||
|
|
9d10832ffc | ||
|
|
ce25cb8ef0 | ||
|
|
eb3891b21f | ||
|
|
0aa4819cea | ||
|
|
a7cc098925 | ||
|
|
0ee3d37524 | ||
|
|
5057bb5b17 | ||
|
|
9abf1de7de | ||
|
|
84f4ec863c | ||
|
|
d271b62543 | ||
|
|
62c796a257 | ||
|
|
9b5c5a5c98 | ||
|
|
2add291375 | ||
|
|
7ac51f1f88 | ||
|
|
1022cf3ff3 | ||
|
|
421711be10 | ||
|
|
475f29c896 | ||
|
|
d00c466843 | ||
|
|
7f26592360 | ||
|
|
4854027a1a | ||
|
|
2961cdad19 | ||
|
|
b76ff0f858 | ||
|
|
bc9d526b7a | ||
|
|
3600582908 | ||
|
|
1e63c48ce4 | ||
|
|
9e7e42eb53 | ||
|
|
b072794d0d | ||
|
|
cc1e432a30 | ||
|
|
47f2143e0d | ||
|
|
7868d9d9c8 | ||
|
|
7001a42149 | ||
|
|
a8f24c9f13 | ||
|
|
e5b7e046d9 | ||
|
|
ef0433a9ba | ||
|
|
a9c4963a4a | ||
|
|
e21db76efe | ||
|
|
bbdc45656c | ||
|
|
c445770261 | ||
|
|
b1c2015321 | ||
|
|
7c4904429f | ||
|
|
d5e86ed077 | ||
|
|
604b042d1b | ||
|
|
e3133f604b | ||
|
|
bfc2d7abbf | ||
|
|
0704b8cd83 | ||
|
|
e81a47a038 | ||
|
|
176ede0002 | ||
|
|
24cc95abcc | ||
|
|
b5e011dae1 | ||
|
|
cdf548cad0 | ||
|
|
5cc2ea2d00 | ||
|
|
527d236ba4 | ||
|
|
8c1c10528f | ||
|
|
7a9b571f6e | ||
|
|
3659ad8b7a | ||
|
|
0d7b95d3ff | ||
|
|
49aaf288cc | ||
|
|
51d7265ec6 | ||
|
|
420336dc78 | ||
|
|
70e77347f3 | ||
|
|
3b786878fd | ||
|
|
64bfcfdc4f | ||
|
|
5c950d2e73 | ||
|
|
0ef22a73fb | ||
|
|
4a27ac5bda |
@@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//===----------------------------------------------------------------------===//
|
||||
// File gets rendered to .circleci/config.yml via git hook.
|
||||
amends "package://pkg.pkl-lang.org/pkl-project-commons/pkl.impl.circleci@1.1.1#/PklCI.pkl"
|
||||
amends "package://pkg.pkl-lang.org/pkl-project-commons/pkl.impl.circleci@1.2.0#/PklCI.pkl"
|
||||
|
||||
import "jobs/BuildNativeJob.pkl"
|
||||
import "jobs/GradleCheckJob.pkl"
|
||||
@@ -81,40 +81,42 @@ triggerPackageDocsBuild = "release"
|
||||
|
||||
local buildNativeJobs: Mapping<String, BuildNativeJob> = new {
|
||||
for (_dist in List("release", "snapshot")) {
|
||||
for (_arch in List("amd64", "aarch64")) {
|
||||
for (_os in List("macOS", "linux")) {
|
||||
["pkl-cli-\(_os)-\(_arch)-\(_dist)"] {
|
||||
arch = _arch
|
||||
os = _os
|
||||
isRelease = _dist == "release"
|
||||
for (_project in List("pkl-cli", "pkl-doc")) {
|
||||
for (_arch in List("amd64", "aarch64")) {
|
||||
for (_os in List("macOS", "linux")) {
|
||||
["\(_project)-\(_os)-\(_arch)-\(_dist)"] {
|
||||
arch = _arch
|
||||
os = _os
|
||||
isRelease = _dist == "release"
|
||||
project = _project
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
["pkl-cli-linux-alpine-amd64-\(_dist)"] {
|
||||
arch = "amd64"
|
||||
os = "linux"
|
||||
musl = true
|
||||
isRelease = _dist == "release"
|
||||
}
|
||||
["pkl-cli-windows-amd64-\(_dist)"] {
|
||||
arch = "amd64"
|
||||
os = "windows"
|
||||
isRelease = _dist == "release"
|
||||
["\(_project)-linux-alpine-amd64-\(_dist)"] {
|
||||
arch = "amd64"
|
||||
os = "linux"
|
||||
musl = true
|
||||
isRelease = _dist == "release"
|
||||
project = _project
|
||||
}
|
||||
["\(_project)-windows-amd64-\(_dist)"] {
|
||||
arch = "amd64"
|
||||
os = "windows"
|
||||
isRelease = _dist == "release"
|
||||
project = _project
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local gradleCheckJobs: Mapping<String, GradleCheckJob> = new {
|
||||
["gradle-check-jdk17"] {
|
||||
javaVersion = "17.0"
|
||||
isRelease = false
|
||||
}
|
||||
["gradle-check-jdk21"] {
|
||||
["gradle-check"] {
|
||||
javaVersion = "21.0"
|
||||
isRelease = false
|
||||
os = "linux"
|
||||
}
|
||||
["gradle-check-jdk17-windows"] {
|
||||
javaVersion = "17.0"
|
||||
["gradle-check-windows"] {
|
||||
javaVersion = "21.0"
|
||||
isRelease = false
|
||||
os = "windows"
|
||||
}
|
||||
@@ -132,8 +134,7 @@ jobs {
|
||||
name = "gradle compatibility"
|
||||
command = #"""
|
||||
:pkl-gradle:build \
|
||||
:pkl-gradle:compatibilityTestReleases \
|
||||
:pkl-gradle:compatibilityTestCandidate
|
||||
:pkl-gradle:compatibilityTestReleases
|
||||
"""#
|
||||
}.job
|
||||
["deploy-snapshot"] = new DeployJob { command = "publishToSonatype" }.job
|
||||
@@ -151,14 +152,15 @@ jobs {
|
||||
name = "Publish release on GitHub"
|
||||
command = #"""
|
||||
# exclude build_artifacts.txt from publish
|
||||
rm -f pkl-cli/build/executable/*.build_artifacts.txt
|
||||
rm -f */build/executable/*.build_artifacts.txt
|
||||
find */build/executable/* -type d | xargs rm -rf
|
||||
gh release create "${CIRCLE_TAG}" \
|
||||
--title "${CIRCLE_TAG}" \
|
||||
--target "${CIRCLE_SHA1}" \
|
||||
--verify-tag \
|
||||
--notes "Release notes: https://pkl-lang.org/main/current/release-notes/changelog.html#release-${CIRCLE_TAG}" \
|
||||
--repo "${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}" \
|
||||
pkl-cli/build/executable/*
|
||||
*/build/executable/*
|
||||
"""#
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,8 +16,7 @@
|
||||
/// Builds the native `pkl` CLI
|
||||
extends "GradleJob.pkl"
|
||||
|
||||
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.1.2#/Config.pkl"
|
||||
import "package://pkg.pkl-lang.org/pkl-pantry/pkl.experimental.uri@1.0.0#/URI.pkl"
|
||||
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.5.0#/Config.pkl"
|
||||
|
||||
/// The architecture to use
|
||||
arch: "amd64"|"aarch64"
|
||||
@@ -25,13 +24,23 @@ arch: "amd64"|"aarch64"
|
||||
/// Whether to link to musl. Otherwise, links to glibc.
|
||||
musl: Boolean = false
|
||||
|
||||
/// The Gradle project under which to generate the executable
|
||||
project: String
|
||||
|
||||
javaVersion = "21.0"
|
||||
|
||||
extraGradleArgs {
|
||||
when (os == "macOS" && arch == "amd64") {
|
||||
"-Dpkl.targetArch=\(arch)"
|
||||
}
|
||||
when (musl) {
|
||||
"-Dpkl.musl=true"
|
||||
}
|
||||
}
|
||||
|
||||
local setupLinuxEnvironment: Config.RunStep =
|
||||
let (jdkVersion = "17.0.9+9")
|
||||
let (muslVersion = "1.2.2")
|
||||
let (zlibVersion = "1.2.13")
|
||||
let (jdkVersionEncoded = URI.encodeComponent(jdkVersion))
|
||||
let (jdkVersionAlt = jdkVersion.replaceLast("+", "_"))
|
||||
let (majorJdkVersion = jdkVersion.split(".").first)
|
||||
new {
|
||||
name = "Set up environment"
|
||||
shell = "#!/bin/bash -exo pipefail"
|
||||
@@ -43,8 +52,8 @@ local setupLinuxEnvironment: Config.RunStep =
|
||||
&& rm -rf /var/cache/dnf
|
||||
|
||||
# install jdk
|
||||
curl -L \
|
||||
https://github.com/adoptium/temurin\#(majorJdkVersion)-binaries/releases/download/jdk-\#(jdkVersionEncoded)/OpenJDK\#(majorJdkVersion)U-jdk_\#(if (arch == "amd64") "x64" else "aarch64")_linux_hotspot_\#(jdkVersionAlt).tar.gz -o /tmp/jdk.tar.gz
|
||||
curl -Lf \
|
||||
https://github.com/adoptium/temurin\#(module.majorJdkVersion)-binaries/releases/download/\#(module.jdkGitHubReleaseName)/OpenJDK\#(module.majorJdkVersion)U-jdk_\#(if (arch == "amd64") "x64" else "aarch64")_linux_hotspot_\#(module.jdkVersionAlt).tar.gz -o /tmp/jdk.tar.gz
|
||||
|
||||
mkdir /jdk \
|
||||
&& cd /jdk \
|
||||
@@ -56,7 +65,7 @@ local setupLinuxEnvironment: Config.RunStep =
|
||||
|
||||
# install zlib
|
||||
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
|
||||
curl -L https://github.com/madler/zlib/releases/download/v\#(zlibVersion)/zlib-\#(zlibVersion).tar.gz -o /tmp/zlib.tar.gz
|
||||
curl -Lf https://github.com/madler/zlib/releases/download/v\#(zlibVersion)/zlib-\#(zlibVersion).tar.gz -o /tmp/zlib.tar.gz
|
||||
|
||||
mkdir -p /tmp/dep_zlib-\#(zlibVersion) \
|
||||
&& cd /tmp/dep_zlib-\#(zlibVersion) \
|
||||
@@ -72,7 +81,7 @@ local setupLinuxEnvironment: Config.RunStep =
|
||||
#"""
|
||||
# install musl
|
||||
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
|
||||
curl -L https://musl.libc.org/releases/musl-\#(muslVersion).tar.gz -o /tmp/musl.tar.gz
|
||||
curl -Lf https://musl.libc.org/releases/musl-\#(muslVersion).tar.gz -o /tmp/musl.tar.gz
|
||||
|
||||
mkdir -p /tmp/dep_musl-\#(muslVersion) \
|
||||
&& cd /tmp/dep_musl-\#(muslVersion) \
|
||||
@@ -90,6 +99,22 @@ local setupLinuxEnvironment: Config.RunStep =
|
||||
}.join("\n\n")
|
||||
}
|
||||
|
||||
local setupMacEnvironment: Config.RunStep =
|
||||
new {
|
||||
name = "Set up environment"
|
||||
shell = "#!/bin/bash -exo pipefail"
|
||||
command =
|
||||
#"""
|
||||
# install jdk
|
||||
curl -Lf \
|
||||
https://github.com/adoptium/temurin\#(module.majorJdkVersion)-binaries/releases/download/\#(module.jdkGitHubReleaseName)/OpenJDK\#(module.majorJdkVersion)U-jdk_\#(if (arch == "amd64") "x64" else "aarch64")_mac_hotspot_\#(module.jdkVersionAlt).tar.gz -o /tmp/jdk.tar.gz
|
||||
|
||||
mkdir $HOME/jdk \
|
||||
&& cd $HOME/jdk \
|
||||
&& cat /tmp/jdk.tar.gz | tar --strip-components=1 -xzC .
|
||||
"""#
|
||||
}
|
||||
|
||||
steps {
|
||||
when (os == "linux") {
|
||||
new Config.RestoreCacheStep {
|
||||
@@ -105,34 +130,31 @@ steps {
|
||||
}
|
||||
}
|
||||
}
|
||||
when (os == "macOS" && arch == "amd64") {
|
||||
new Config.RunStep {
|
||||
name = "Installing Rosetta 2"
|
||||
command = """
|
||||
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
|
||||
"""
|
||||
when (os == "macOS") {
|
||||
when (arch == "amd64") {
|
||||
new Config.RunStep {
|
||||
name = "Installing Rosetta 2"
|
||||
command = """
|
||||
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
|
||||
"""
|
||||
}
|
||||
}
|
||||
setupMacEnvironment
|
||||
}
|
||||
new Config.RunStep {
|
||||
name = "gradle buildNative"
|
||||
local _os =
|
||||
if (module.os == "macOS") "mac"
|
||||
else if (musl) "alpine"
|
||||
else if (module.os == "windows") "windows"
|
||||
else "linux"
|
||||
local jobName = "\(_os)Executable\(arch.capitalize())"
|
||||
when (module.os == "windows") {
|
||||
shell = "bash.exe"
|
||||
}
|
||||
command = #"""
|
||||
export PATH=~/staticdeps/bin:$PATH
|
||||
./gradlew \#(module.gradleArgs) pkl-cli:\#(jobName) pkl-core:test\#(jobName.capitalize()) pkl-server:test\#(jobName.capitalize())
|
||||
./gradlew \#(module.gradleArgs) \#(project):buildNative
|
||||
"""#
|
||||
}
|
||||
new Config.PersistToWorkspaceStep {
|
||||
root = "."
|
||||
paths {
|
||||
"pkl-cli/build/executable/"
|
||||
"\(project)/build/executable/"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -142,10 +164,13 @@ job {
|
||||
macos {
|
||||
xcode = "15.3.0"
|
||||
}
|
||||
resource_class = "macos.m1.large.gen1"
|
||||
resource_class = "m2pro.large"
|
||||
environment {
|
||||
["JAVA_HOME"] = "/Users/distiller/jdk/Contents/Home"
|
||||
}
|
||||
}
|
||||
when (os == "linux") {
|
||||
docker {
|
||||
docker = new Listing<Config.DockerImage> {
|
||||
new {
|
||||
image = if (arch == "aarch64") "arm64v8/oraclelinux:8-slim" else "oraclelinux:8-slim"
|
||||
}
|
||||
@@ -160,5 +185,8 @@ job {
|
||||
image = "windows-server-2022-gui:current"
|
||||
}
|
||||
resource_class = "windows.large"
|
||||
environment {
|
||||
["JAVA_HOME"] = "/jdk"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,17 +15,13 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
extends "GradleJob.pkl"
|
||||
|
||||
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.1.2#/Config.pkl"
|
||||
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.5.0#/Config.pkl"
|
||||
|
||||
local self = this
|
||||
|
||||
command: String
|
||||
javaVersion = "21.0"
|
||||
|
||||
job {
|
||||
docker {
|
||||
new { image = "cimg/openjdk:17.0" }
|
||||
}
|
||||
}
|
||||
command: String
|
||||
|
||||
os = "linux"
|
||||
|
||||
@@ -34,11 +30,14 @@ steps {
|
||||
new Config.RunStep {
|
||||
command = "./gradlew \(self.gradleArgs) \(module.command)"
|
||||
}
|
||||
// add jpkl to workspace so it gets published as a GitHub release
|
||||
// add Java executables to workspace so they get published as a GitHub release
|
||||
new Config.PersistToWorkspaceStep {
|
||||
root = "."
|
||||
paths {
|
||||
"pkl-cli/build/executable/"
|
||||
"pkl-doc/build/executable/"
|
||||
"pkl-codegen-java/build/executable/"
|
||||
"pkl-codegen-kotlin/build/executable/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
extends "GradleJob.pkl"
|
||||
|
||||
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.1.2#/Config.pkl"
|
||||
|
||||
javaVersion: "17.0"|"21.0"
|
||||
|
||||
os = "linux"
|
||||
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.5.0#/Config.pkl"
|
||||
|
||||
steps {
|
||||
new Config.RunStep {
|
||||
@@ -27,19 +23,3 @@ steps {
|
||||
command = "./gradlew \(module.gradleArgs) check"
|
||||
}
|
||||
}
|
||||
|
||||
job {
|
||||
when (os == "linux") {
|
||||
docker {
|
||||
new {
|
||||
image = "cimg/openjdk:\(javaVersion)"
|
||||
}
|
||||
}
|
||||
}
|
||||
when (os == "windows") {
|
||||
machine {
|
||||
image = "windows-server-2022-gui:current"
|
||||
}
|
||||
resource_class = "windows.large"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
abstract module GradleJob
|
||||
|
||||
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.1.2#/Config.pkl"
|
||||
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.5.0#/Config.pkl"
|
||||
import "package://pkg.pkl-lang.org/pkl-pantry/pkl.experimental.uri@1.0.3#/URI.pkl"
|
||||
|
||||
/// Whether this is a release build or not.
|
||||
isRelease: Boolean = false
|
||||
@@ -23,23 +24,78 @@ isRelease: Boolean = false
|
||||
/// The OS to run on
|
||||
os: "macOS"|"linux"|"windows"
|
||||
|
||||
/// The version of Java to use.
|
||||
javaVersion: "17.0"|"21.0"
|
||||
|
||||
fixed javaVersionFull =
|
||||
if (javaVersion == "17.0") "17.0.9+9"
|
||||
else "21.0.5+11"
|
||||
|
||||
fixed jdkVersionAlt = javaVersionFull.replaceLast("+", "_")
|
||||
|
||||
fixed majorJdkVersion = javaVersionFull.split(".").first
|
||||
|
||||
fixed jdkGitHubReleaseName =
|
||||
let (ver =
|
||||
// 17.0.9+9 is missing some binaries (see https://github.com/adoptium/adoptium-support/issues/994)
|
||||
if (javaVersionFull == "17.0.9+9" && os == "windows") "jdk-17.0.9+9.1"
|
||||
else "jdk-\(javaVersionFull)"
|
||||
)
|
||||
URI.encodeComponent(ver)
|
||||
|
||||
fixed gradleArgs = new Listing {
|
||||
"--info"
|
||||
"--stacktrace"
|
||||
"-DtestReportsDir=${HOME}/test-results"
|
||||
"-DpklMultiJdkTesting=true"
|
||||
when (isRelease) {
|
||||
"-DreleaseBuild=true"
|
||||
}
|
||||
...extraGradleArgs
|
||||
}.join(" ")
|
||||
|
||||
extraGradleArgs: Listing<String>
|
||||
|
||||
steps: Listing<Config.Step>
|
||||
|
||||
job: Config.Job = new {
|
||||
environment {
|
||||
["LANG"] = "en_US.UTF-8"
|
||||
when (os == "windows") {
|
||||
["JAVA_HOME"] = "/jdk"
|
||||
}
|
||||
}
|
||||
when (os == "linux") {
|
||||
docker {
|
||||
new {
|
||||
image = "cimg/openjdk:\(javaVersion)"
|
||||
}
|
||||
}
|
||||
}
|
||||
when (os == "windows") {
|
||||
machine {
|
||||
image = "windows-server-2022-gui:current"
|
||||
}
|
||||
resource_class = "windows.large"
|
||||
}
|
||||
steps {
|
||||
"checkout"
|
||||
when (os == "windows") {
|
||||
new Config.RunStep {
|
||||
name = "Set up environment"
|
||||
shell = "bash.exe"
|
||||
command = #"""
|
||||
# install jdk
|
||||
curl -Lf \
|
||||
https://github.com/adoptium/temurin\#(majorJdkVersion)-binaries/releases/download/\#(jdkGitHubReleaseName)/OpenJDK\#(majorJdkVersion)U-jdk_x64_windows_hotspot_\#(jdkVersionAlt).zip -o /tmp/jdk.zip
|
||||
|
||||
unzip /tmp/jdk.zip -d /tmp/jdk \
|
||||
&& cd /tmp/jdk/jdk-* \
|
||||
&& mkdir /jdk \
|
||||
&& cp -r . /jdk
|
||||
"""#
|
||||
}
|
||||
}
|
||||
...module.steps
|
||||
new Config.StoreTestResults {
|
||||
path = "~/test-results"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
extends "GradleJob.pkl"
|
||||
|
||||
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.1.2#/Config.pkl"
|
||||
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.5.0#/Config.pkl"
|
||||
|
||||
name: String = command
|
||||
|
||||
@@ -23,6 +23,8 @@ command: String
|
||||
|
||||
os = "linux"
|
||||
|
||||
javaVersion = "21.0"
|
||||
|
||||
steps {
|
||||
new Config.RunStep {
|
||||
name = module.name
|
||||
@@ -31,9 +33,3 @@ steps {
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
job {
|
||||
docker {
|
||||
new { image = "cimg/openjdk:17.0" }
|
||||
}
|
||||
}
|
||||
|
||||
2
.git-blame-ignore-revs
Normal file
2
.git-blame-ignore-revs
Normal file
@@ -0,0 +1,2 @@
|
||||
# Auto-format Kotlin code
|
||||
816cd483c8adf4c04e14236c173a1dc6bd2579ea
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -5,6 +5,7 @@
|
||||
.gradle/
|
||||
build/
|
||||
generated/
|
||||
testgenerated/
|
||||
|
||||
# IntelliJ
|
||||
.idea/
|
||||
@@ -15,6 +16,8 @@ generated/
|
||||
!.idea/scopes/
|
||||
!.idea/vcs.xml
|
||||
|
||||
# :pkl-core:makeIntelliJAntlrPluginHappy
|
||||
gen/
|
||||
PklLexer.tokens
|
||||
.vscode/
|
||||
|
||||
.pkl-lsp/
|
||||
|
||||
.kotlin/
|
||||
|
||||
2
.idea/inspectionProfiles/Project_Default.xml
generated
2
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -74,4 +74,4 @@
|
||||
<option name="processComments" value="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
</component>
|
||||
|
||||
@@ -1 +1 @@
|
||||
17.0
|
||||
21
|
||||
|
||||
2
.mailmap
Normal file
2
.mailmap
Normal file
@@ -0,0 +1,2 @@
|
||||
Jen Basch <421772+HT154@users.noreply.github.com>
|
||||
Jen Basch <jbasch@apple.com>
|
||||
@@ -2,19 +2,22 @@
|
||||
:uri-gng: https://gng.dsun.org
|
||||
:uri-jenv: https://www.jenv.be
|
||||
:uri-intellij: https://www.jetbrains.com/idea/download/
|
||||
:uri-jdk: https://adoptopenjdk.net/releases.html?variant=openjdk17
|
||||
:uri-native-prerequisites-linux: https://www.graalvm.org/latest/getting-started/linux/#prerequisites-for-native-image-on-linux
|
||||
:uri-native-prerequisites-windows: https://www.graalvm.org/latest/getting-started/windows/#prerequisites-for-native-image-on-windows
|
||||
|
||||
== Setup
|
||||
|
||||
. (mandatory) Install {uri-jdk}[OpenJDK 17] or higher
|
||||
. (recommended) Install {uri-intellij}[IntelliJ IDEA 2023.x] +
|
||||
. (mandatory) Install a JDK (JDK 21+ required).
|
||||
. (recommended) Install {uri-intellij}[IntelliJ IDEA] +
|
||||
To import the project into IntelliJ, go to File->Open and select the project's root directory.
|
||||
If the project is opened but not imported, look for a popup in the lower right corner
|
||||
and click its "Import Gradle Project" link.
|
||||
. (recommended) Install {uri-gng}[gng] +
|
||||
_gng_ enables to run Gradle commands with `gw` (instead of `./gradlew`) from any subdirectory.
|
||||
. (recommended) Set up Git ignore-revs +
|
||||
`git config blame.ignoreRevsFile .git-blame-ignore-revs`
|
||||
. (recommended) Install {uri-jenv}[jenv] and plugins +
|
||||
_jenv_ use specific JDK versions in certain subdirectories. _Pkl_ comes with a `.java-version` file specifying JDK 17. +
|
||||
_jenv_ use specific JDK versions in certain subdirectories. _Pkl_ comes with a `.java-version` file specifying JDK 21. +
|
||||
Enable _jenv_ plugins for better handling by `gradle`:
|
||||
+
|
||||
[source,shell]
|
||||
@@ -22,22 +25,35 @@ Enable _jenv_ plugins for better handling by `gradle`:
|
||||
jenv enable-plugin gradle
|
||||
jenv enable-plugin export
|
||||
----
|
||||
. (optional) If you've named the original apple/pkl git repository something other than `origin`, set env var `PKL_ORIGINAL_REMOTE_NAME` to that name in your `.bashrc`, `.zshrc`, `config.fish` or however you manage your local environment.
|
||||
+
|
||||
This will allow spotless to pick the correct starting branch when formatting source code files.
|
||||
Otherwise, you might see that _every_ file has its copyright year updated.
|
||||
|
||||
=== Additional Linux Setup
|
||||
. (optional) To build the native executable (`./gradlew buildNative`),
|
||||
install {uri-native-prerequisites-linux}[Prerequisites For Native Image on Linux].
|
||||
|
||||
=== Additional Windows Setup
|
||||
. (optional) Go to `System->For developers` and enable `Developer Mode`.
|
||||
Otherwise, some tests may fail due to insufficient file system privileges.
|
||||
. (optional) To build the native executable (`./gradlew buildNative`),
|
||||
install {uri-native-prerequisites-windows}[Prerequisites For Native Image on Windows].
|
||||
|
||||
== Common Build Commands
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
gw clean
|
||||
gw test # run all tests except native executable tests
|
||||
gw testNative # run native executable tests
|
||||
gw spotlessApply # fix code formatting
|
||||
gw build # build everything except native executables
|
||||
gw buildNative # build macOS executable on macOS,
|
||||
# Linux and Alpine executables on Linux
|
||||
# (Alpine executable is only built if ~/staticdeps/bin/musl-gcc exists)
|
||||
gw test # run all tests except native executable tests
|
||||
gw spotlessApply # fix code formatting
|
||||
gw build # build everything except native executables
|
||||
gw pkl-cli:testNative # run native executable tests
|
||||
gw pkl-cli:buildNative # build native executable for current platform
|
||||
|
||||
pkl-cli/build/executable/jpkl # run Java executable
|
||||
pkl-cli/build/executable/pkl-macos-amd64 # run Mac executable
|
||||
pkl-cli/build/executable/pkl-macos-aarch64 # run Mac executable
|
||||
pkl-cli/build/executable/pkl-macos-amd64 # run Intel Mac executable
|
||||
pkl-cli/build/executable/pkl-linux-amd64 # run Linux executable
|
||||
pkl-cli/build/executable/pkl-alpine-linux-amd64 # run Alpine Linux executable
|
||||
pkl-cli/build/executable/pkl-windows-amd64.exe # run Windows executable
|
||||
@@ -66,8 +82,6 @@ based on version information from https://search.maven.org, https://plugins.grad
|
||||
|
||||
* Truffle code generation is performed by Truffle's annotation processor, which runs as part of task `:pkl-core:compileJava`
|
||||
** Output dir is `generated/truffle/`
|
||||
* ANTLR code generation is performed by task `:pkl-core:generateGrammarSource`
|
||||
** Output dir is `generated/antlr/`
|
||||
|
||||
== Remote JVM Debugging
|
||||
|
||||
@@ -79,12 +93,6 @@ Example: `./gradlew test -Djvmdebug=true`
|
||||
== Resources
|
||||
For automated build setup examples see our https://github.com/apple/pkl/blob/main/.circleci/[CircleCI] jobs like our https://github.com/apple/pkl/blob/main/.circleci/jobs/BuildNativeJob.pkl[BuildNativeJob.pkl], where we build Pkl automatically.
|
||||
|
||||
=== ANTLR
|
||||
|
||||
* https://github.com/antlr/antlr4/blob/main/doc/index.md[Documentation]
|
||||
* https://groups.google.com/forum/#!forum/antlr-discussion[Forums]
|
||||
* https://github.com/mobileink/lab.clj.antlr/tree/main/doc[Some third-party docs]
|
||||
|
||||
=== Truffle
|
||||
|
||||
* http://ssw.jku.at/Research/Projects/JVM/Truffle.html[Homepage]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright © 2024 Apple Inc. and the Pkl project authors
|
||||
Copyright © 2024-2025 Apple Inc. and the Pkl project authors
|
||||
|
||||
|
||||
Portions of this software were originally based on 'SnakeYAML' developed by Andrey Somov.
|
||||
|
||||
70
README.adoc
70
README.adoc
@@ -41,3 +41,73 @@ We'd love to hear from you!
|
||||
* link:CONTRIBUTING.adoc[] for tips on pull requests and filing issues
|
||||
* link:DEVELOPMENT.adoc[] for build instructions
|
||||
* {uri-ci-artifacts}[Sonatype Repository] for the artifacts/binaries built by our {uri-ci-pipeline}[CI pipelines] (and those of our other tools and packages repositories).
|
||||
|
||||
== Pkl GitHub Repositories
|
||||
|
||||
[%autowidth]
|
||||
|===
|
||||
|Name |Description
|
||||
|
||||
|`apple/pkl`
|
||||
|A configuration as code language with rich validation and tooling.
|
||||
|
||||
|https://github.com/apple/pkl-evolution[`apple/pkl-evolution`]
|
||||
|Suggested Pkl Improvements, Changes, or Enhancements (SPICEs)
|
||||
|
||||
|https://github.com/apple/pkl-go[`apple/pkl-go`]
|
||||
|Pkl bindings for the Go programming language
|
||||
|
||||
|https://github.com/apple/pkl-go-examples[`apple/pkl-go-examples`]
|
||||
|Examples for using Pkl within Go applications
|
||||
|
||||
|https://github.com/apple/pkl-intellij[`apple/pkl-intellij`]
|
||||
|JetBrains editor plugins providing Pkl language support
|
||||
|
||||
|https://github.com/apple/pkl-jvm-examples[`apple/pkl-jvm-examples`]
|
||||
|Examples for using Pkl within JVM applications
|
||||
|
||||
|https://github.com/apple/pkl-k8s[`apple/pkl-k8s`]
|
||||
|Templates for using Pkl with Kubernetes
|
||||
|
||||
|https://github.com/apple/pkl-k8s-examples[`apple/pkl-k8s-examples`]
|
||||
|Examples for using Pkl with Kubernetes
|
||||
|
||||
|https://github.com/apple/pkl-lang.org[`apple/pkl-lang.org`]
|
||||
|The pkl-lang.org website
|
||||
|
||||
|https://github.com/apple/pkl-lsp[`apple/pkl-lsp`]
|
||||
| Language server for Pkl, implementing the server-side of the Language Server Protocol
|
||||
|
||||
|https://github.com/apple/pkl-neovim[`apple/pkl-neovim`]
|
||||
|Pkl language support for Neovim
|
||||
|
||||
|https://github.com/apple/pkl-package-docs[`apple/pkl-package-docs`]
|
||||
|Documentation for Pkl packages
|
||||
|
||||
|https://github.com/apple/pkl-pantry[`apple/pkl-pantry`]
|
||||
|Shared Pkl packages
|
||||
|
||||
|https://github.com/apple/pkl-project-commons[`apple/pkl-project-commons`]
|
||||
|Utility libraries for Pkl
|
||||
|
||||
|https://github.com/apple/pkl-spring[`apple/pkl-spring`]
|
||||
|Spring Boot extension for configuring Boot apps with Pkl
|
||||
|
||||
|https://github.com/apple/pkl-swift[`apple/pkl-swift`]
|
||||
|Pkl bindings for the Swift programming language
|
||||
|
||||
|https://github.com/apple/pkl-swift-examples[`apple/pkl-swift-examples`]
|
||||
|Examples for using Pkl within Swift applications
|
||||
|
||||
|https://github.com/apple/pkl-vscode[`apple/pkl-vscode`]
|
||||
|Pkl language support for VS Code
|
||||
|
||||
|https://github.com/apple/pkl.tmbundle[`apple/pkl.tmbundle`]
|
||||
|TextMate bundle for Pkl
|
||||
|
||||
|https://github.com/apple/rules_pkl[`apple/rules_pkl`]
|
||||
| Bazel build rules for Pkl
|
||||
|
||||
|https://github.com/apple/tree-sitter-pkl[`apple/tree-sitter-pkl`]
|
||||
|Tree-sitter parser for Pkl
|
||||
|===
|
||||
|
||||
@@ -26,18 +26,7 @@ Copyright © 2017 Square, Inc.
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
4) ANTLR 4 Runtime (Optimized) (http://tunnelvisionlabs.com)
|
||||
POM License: The BSD License - http://www.antlr.org/license.html
|
||||
|
||||
Copyright (c) 2012 Terence Parr and Sam Harwell
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
5) GeantyRef (https://github.com/leangen/geantyref)
|
||||
4) GeantyRef (https://github.com/leangen/geantyref)
|
||||
Manifest license URL: https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
@@ -47,7 +36,7 @@ Copyright © 2017 Kaqqao
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
6) commonmark-java core
|
||||
5) commonmark-java core
|
||||
POM License: The 2-Clause BSD License - https://opensource.org/licenses/BSD-2-Clause
|
||||
|
||||
Embedded license:
|
||||
@@ -78,7 +67,7 @@ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
7) commonmark-java extension for tables
|
||||
6) commonmark-java extension for tables
|
||||
POM License: The 2-Clause BSD License - https://opensource.org/licenses/BSD-2-Clause
|
||||
|
||||
Embedded license:
|
||||
@@ -109,7 +98,7 @@ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
8) jansi (http://fusesource.com/)
|
||||
7) jansi (http://fusesource.com/)
|
||||
Manifest license URL: https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
@@ -119,13 +108,13 @@ Copyright © Fusesource 2023
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
9) Graal Sdk (https://github.com/oracle/graal)
|
||||
8) Graal Sdk (https://github.com/oracle/graal)
|
||||
POM License: Universal Permissive License, Version 1.0 - http://opensource.org/licenses/UPL
|
||||
|
||||
10) Truffle API (http://openjdk.java.net/projects/graal)
|
||||
9) Truffle API (http://openjdk.java.net/projects/graal)
|
||||
POM License: Universal Permissive License, Version 1.0 - http://opensource.org/licenses/UPL
|
||||
|
||||
11) IntelliJ IDEA Annotations (http://www.jetbrains.org)
|
||||
10) IntelliJ IDEA Annotations (http://www.jetbrains.org)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
@@ -133,7 +122,7 @@ Copyright © Jetbrains 2023
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
12) kotlin-reflect (https://kotlinlang.org/)
|
||||
11) kotlin-reflect (https://kotlinlang.org/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
@@ -141,7 +130,7 @@ Copyright © Wuseal 2018
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
13) kotlin-stdlib (https://kotlinlang.org/)
|
||||
12) kotlin-stdlib (https://kotlinlang.org/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
@@ -149,7 +138,7 @@ Copyright © 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contribu
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
14) kotlin-stdlib-common (https://kotlinlang.org/)
|
||||
13) kotlin-stdlib-common (https://kotlinlang.org/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
@@ -157,7 +146,7 @@ Copyright © 2023 Kotlin Team
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
15) kotlin-stdlib-jdk7 (https://kotlinlang.org/)
|
||||
14) kotlin-stdlib-jdk7 (https://kotlinlang.org/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
@@ -165,7 +154,7 @@ Copyright © 2023 Kotlin Team
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
16) kotlin-stdlib-jdk8 (https://kotlinlang.org/)
|
||||
15) kotlin-stdlib-jdk8 (https://kotlinlang.org/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
@@ -173,7 +162,7 @@ Copyright © 2023 Kotlin Team
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
17) kotlinx.html (https://github.com/Kotlin/kotlinx.html)
|
||||
16) kotlinx.html (https://github.com/Kotlin/kotlinx.html)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
@@ -181,7 +170,7 @@ Copyright © 2017 Yole
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
18) kotlinx-serialization-core (https://github.com/Kotlin/kotlinx.serialization)
|
||||
17) kotlinx-serialization-core (https://github.com/Kotlin/kotlinx.serialization)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
@@ -189,7 +178,7 @@ The Apache License
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
19) kotlinx-serialization-json (https://github.com/Kotlin/kotlinx.serialization)
|
||||
18) kotlinx-serialization-json (https://github.com/Kotlin/kotlinx.serialization)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
@@ -197,7 +186,7 @@ The Apache License
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
20) JLine Reader
|
||||
19) JLine Reader
|
||||
Manifest license URL: https://opensource.org/licenses/BSD-3-Clause
|
||||
|
||||
POM License: The 3-Clause BSD License - https://opensource.org/licenses/BSD-3-Clause
|
||||
@@ -216,7 +205,7 @@ software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
21) JLine Terminal
|
||||
20) JLine Terminal
|
||||
Manifest license URL: https://opensource.org/licenses/BSD-3-Clause
|
||||
|
||||
POM License: The 3-Clause BSD License - https://opensource.org/licenses/BSD-3-Clause
|
||||
@@ -235,7 +224,7 @@ software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
22) JLine JANSI Terminal
|
||||
21) JLine JANSI Terminal
|
||||
Manifest license URL: https://opensource.org/licenses/BSD-3-Clause
|
||||
|
||||
POM License: The 3-Clause BSD License - https://opensource.org/licenses/BSD-3-Clause
|
||||
@@ -254,7 +243,7 @@ software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
23) msgpack-core (https://msgpack.org/)
|
||||
22) msgpack-core (https://msgpack.org/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
@@ -262,7 +251,7 @@ Copyright © 2016 Sadayuki Furuhashi, Muga Nishizawa, Taro L. Saito, Mitsunori K
|
||||
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
24) Paguro (https://github.com/GlenKPeterson/Paguro)
|
||||
23) Paguro (https://github.com/GlenKPeterson/Paguro)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
@@ -364,7 +353,7 @@ Everyone is permitted to copy and distribute copies of this Agreement, but in or
|
||||
|
||||
This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
|
||||
|
||||
25) SnakeYAML Engine (http://www.snakeyaml.org)
|
||||
24) SnakeYAML Engine (http://www.snakeyaml.org)
|
||||
Manifest license URL: https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
@@ -1,31 +1,45 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
plugins {
|
||||
pklAllProjects
|
||||
pklJavaLibrary
|
||||
pklGraalVm
|
||||
id("me.champeau.jmh")
|
||||
}
|
||||
|
||||
val truffle: Configuration by configurations.creating
|
||||
val graal: Configuration by configurations.creating
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
dependencies {
|
||||
jmh(projects.pklCore)
|
||||
// necessary because antlr4-runtime is declared as implementation dependency in pkl-core.gradle
|
||||
jmh(libs.antlrRuntime)
|
||||
jmh(projects.pklCommonsTest)
|
||||
jmh(projects.pklParser)
|
||||
truffle(libs.truffleApi)
|
||||
graal(libs.graalCompiler)
|
||||
}
|
||||
|
||||
jmh {
|
||||
//include = ["fib_class_java"]
|
||||
//include = ["fib_class_constrained1", "fib_class_constrained2"]
|
||||
// include = ["fib_class_java"]
|
||||
// include = ["fib_class_constrained1", "fib_class_constrained2"]
|
||||
jmhVersion.set(libs.versions.jmh)
|
||||
// jvmArgsAppend = "-Dgraal.TruffleCompilationExceptionsAreFatal=true " +
|
||||
// "-Dgraal.Dump=Truffle,TruffleTree -Dgraal.TraceTruffleCompilation=true " +
|
||||
// "-Dgraal.TruffleFunctionInlining=false"
|
||||
jvm.set("${buildInfo.graalVmAmd64.baseDir}/bin/java")
|
||||
// see: https://docs.oracle.com/en/graalvm/enterprise/20/docs/graalvm-as-a-platform/implement-language/#disable-class-path-separation
|
||||
// see:
|
||||
// https://docs.oracle.com/en/graalvm/enterprise/20/docs/graalvm-as-a-platform/implement-language/#disable-class-path-separation
|
||||
jvmArgs.set(
|
||||
listOf(
|
||||
// one JVM arg per list element doesn't work, but the following does
|
||||
@@ -33,16 +47,13 @@ jmh {
|
||||
)
|
||||
)
|
||||
includeTests.set(false)
|
||||
//threads = Runtime.runtime.availableProcessors() / 2 + 1
|
||||
//synchronizeIterations = false
|
||||
// threads = Runtime.runtime.availableProcessors() / 2 + 1
|
||||
// synchronizeIterations = false
|
||||
}
|
||||
|
||||
tasks.named("jmh") {
|
||||
dependsOn(":installGraalVmAmd64")
|
||||
}
|
||||
tasks.named("jmh") { dependsOn(":installGraalVmAmd64") }
|
||||
|
||||
// Prevent this error which occurs when building in IntelliJ:
|
||||
// "Entry org/pkl/core/fib_class_typed.pkl is a duplicate but no duplicate handling strategy has been set."
|
||||
tasks.processJmhResources {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
// "Entry org/pkl/core/fib_class_typed.pkl is a duplicate but no duplicate handling strategy has
|
||||
// been set."
|
||||
tasks.processJmhResources { duplicatesStrategy = DuplicatesStrategy.EXCLUDE }
|
||||
|
||||
@@ -1,43 +1,54 @@
|
||||
# This is a Gradle generated file for dependency locking.
|
||||
# Manual edits can break the build and are not advised.
|
||||
# This file is expected to be part of source control.
|
||||
com.tunnelvisionlabs:antlr4-runtime:4.9.0=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy:1.14.16=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
net.bytebuddy:byte-buddy:1.15.11=jmh,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.sf.jopt-simple:jopt-simple:5.0.4=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
org.apache.commons:commons-math3:3.6.1=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
|
||||
org.assertj:assertj-core:3.26.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.compiler:compiler:23.0.2=graal
|
||||
org.graalvm.sdk:graal-sdk:23.0.2=graal,jmh,jmhRuntimeClasspath,truffle
|
||||
org.graalvm.truffle:truffle-api:23.0.2=graal,jmh,jmhRuntimeClasspath,truffle
|
||||
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.7.10=kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains:annotations:13.0=kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.jupiter:junit-jupiter-engine:5.10.2=testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.jupiter:junit-jupiter-params:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.platform:junit-platform-engine:1.10.2=testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit:junit-bom:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.apiguardian:apiguardian-api:1.1.2=jmhCompileClasspath,jmhImplementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata
|
||||
org.assertj:assertj-core:3.27.3=jmh,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.compiler:compiler:24.1.2=graal
|
||||
org.graalvm.polyglot:polyglot:24.1.2=jmh,jmhRuntimeClasspath,truffle
|
||||
org.graalvm.sdk:collections:24.1.2=graal,jmh,jmhRuntimeClasspath,truffle
|
||||
org.graalvm.sdk:graal-sdk:24.1.2=jmh,jmhRuntimeClasspath
|
||||
org.graalvm.sdk:nativeimage:24.1.2=jmh,jmhRuntimeClasspath,truffle
|
||||
org.graalvm.sdk:word:24.1.2=graal,jmh,jmhRuntimeClasspath,truffle
|
||||
org.graalvm.truffle:truffle-api:24.1.2=jmh,jmhRuntimeClasspath,truffle
|
||||
org.graalvm.truffle:truffle-compiler:24.1.2=graal
|
||||
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-common:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:2.0.21=kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-native-prebuilt:2.0.21=kotlinNativeBundleConfiguration
|
||||
org.jetbrains.kotlin:kotlin-reflect:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.0.21=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.0.21=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.0.21=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains:annotations:13.0=jmh,jmhCompileClasspath,jmhRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.13.3=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-engine:5.13.3=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-params:5.13.3=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.13.3=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-engine:1.13.3=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-launcher:1.13.3=testRuntimeClasspath
|
||||
org.junit:junit-bom:5.13.3=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.msgpack:msgpack-core:0.9.8=jmh,jmhRuntimeClasspath
|
||||
org.openjdk.jmh:jmh-core:1.37=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
org.openjdk.jmh:jmh-generator-asm:1.37=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
org.openjdk.jmh:jmh-generator-bytecode:1.37=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
org.openjdk.jmh:jmh-generator-reflection:1.37=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.opentest4j:opentest4j:1.3.0=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.organicdesign:Paguro:3.10.3=jmh,jmhRuntimeClasspath
|
||||
org.ow2.asm:asm:9.0=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
org.snakeyaml:snakeyaml-engine:2.5=jmh,jmhRuntimeClasspath
|
||||
empty=annotationProcessor,apiDependenciesMetadata,archives,compile,compileClasspath,compileOnly,compileOnlyDependenciesMetadata,default,implementationDependenciesMetadata,intransitiveDependenciesMetadata,jmhAnnotationProcessor,jmhApiDependenciesMetadata,jmhCompile,jmhCompileOnly,jmhCompileOnlyDependenciesMetadata,jmhIntransitiveDependenciesMetadata,jmhKotlinScriptDef,jmhKotlinScriptDefExtensions,jmhRuntime,jmhRuntimeOnlyDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtime,runtimeClasspath,runtimeOnlyDependenciesMetadata,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompile,testCompileOnly,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDef,testKotlinScriptDefExtensions,testRuntime
|
||||
org.snakeyaml:snakeyaml-engine:2.10=jmh,jmhRuntimeClasspath
|
||||
empty=annotationProcessor,apiDependenciesMetadata,compileClasspath,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,jmhAnnotationProcessor,jmhApiDependenciesMetadata,jmhCompileOnlyDependenciesMetadata,jmhIntransitiveDependenciesMetadata,jmhKotlinScriptDefExtensions,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,runtimeClasspath,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -50,7 +50,8 @@ public class ListSort {
|
||||
null,
|
||||
null,
|
||||
IoUtils.getCurrentWorkingDir(),
|
||||
StackFrameTransformers.defaultTransformer);
|
||||
StackFrameTransformers.defaultTransformer,
|
||||
false);
|
||||
private static final List<Object> list = new ArrayList<>(100000);
|
||||
|
||||
static {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,8 +15,17 @@
|
||||
*/
|
||||
package org.pkl.core.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
import org.pkl.commons.test.FileTestUtils;
|
||||
import org.pkl.commons.test.FileTestUtilsKt;
|
||||
import org.pkl.core.Release;
|
||||
import org.pkl.core.util.IoUtils;
|
||||
import org.pkl.parser.Parser;
|
||||
import org.pkl.parser.ParserError;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Warmup(iterations = 5, time = 2)
|
||||
@@ -24,37 +33,33 @@ import org.openjdk.jmh.annotations.*;
|
||||
@OutputTimeUnit(TimeUnit.SECONDS)
|
||||
@Fork(1)
|
||||
public class ParserBenchmark {
|
||||
// One-time execution of this code took ~10s until moving rule alternative
|
||||
// for parenthesized expression after alternative for anonymous function.
|
||||
@Benchmark
|
||||
public void run() {
|
||||
new Parser()
|
||||
.parseModule(
|
||||
"""
|
||||
a1 {
|
||||
a2 {
|
||||
a3 {
|
||||
a4 {
|
||||
a5 {
|
||||
a6 {
|
||||
a7 {
|
||||
a8 {
|
||||
a9 {
|
||||
a10 {
|
||||
a11 {
|
||||
a12 {
|
||||
a13 = map(map(map((x) -> 1)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}""");
|
||||
public void parseStdlib() {
|
||||
for (var stdlibModule : Release.current().standardLibrary().modules()) {
|
||||
try {
|
||||
var moduleSource =
|
||||
IoUtils.readClassPathResourceAsString(
|
||||
getClass(), "/org/pkl/core/stdlib/%s.pkl".formatted(stdlibModule.substring(4)));
|
||||
new Parser().parseModule(moduleSource);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void parseSnippetTests() {
|
||||
var snippetTestDir =
|
||||
FileTestUtils.getRootProjectDir()
|
||||
.resolve("pkl-core/src/test/files/LanguageSnippetTests/input");
|
||||
for (var snippet : FileTestUtilsKt.listFilesRecursively(snippetTestDir)) {
|
||||
try {
|
||||
var moduleSource = Files.readString(snippet);
|
||||
new Parser().parseModule(moduleSource);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
} catch (ParserError ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// https://youtrack.jetbrains.com/issue/KTIJ-19369
|
||||
@file:Suppress("DSL_SCOPE_VIOLATION")
|
||||
@file:Suppress("DSL_SCOPE_VIOLATION")
|
||||
|
||||
import org.jetbrains.gradle.ext.ActionDelegationConfig
|
||||
import org.jetbrains.gradle.ext.ActionDelegationConfig.TestRunner.PLATFORM
|
||||
import org.jetbrains.gradle.ext.ProjectSettings
|
||||
import org.jetbrains.gradle.ext.TaskTriggersConfig
|
||||
|
||||
plugins {
|
||||
pklAllProjects
|
||||
@@ -18,8 +32,8 @@ plugins {
|
||||
nexusPublishing {
|
||||
repositories {
|
||||
sonatype {
|
||||
nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/"))
|
||||
snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/"))
|
||||
nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/"))
|
||||
snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,22 +47,16 @@ idea {
|
||||
delegateBuildRunToGradle = true
|
||||
testRunner = PLATFORM
|
||||
}
|
||||
configure<TaskTriggersConfig> {
|
||||
afterSync(provider { project(":pkl-core").tasks.named("makeIntelliJAntlrPluginHappy") })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val clean by tasks.registering(Delete::class) {
|
||||
delete(layout.buildDirectory)
|
||||
}
|
||||
val clean by tasks.existing { delete(layout.buildDirectory) }
|
||||
|
||||
val printVersion by tasks.registering {
|
||||
doFirst { println(buildInfo.pklVersion) }
|
||||
}
|
||||
val printVersion by tasks.registering { doFirst { println(buildInfo.pklVersion) } }
|
||||
|
||||
val message = """
|
||||
val message =
|
||||
"""
|
||||
====
|
||||
Gradle version : ${gradle.gradleVersion}
|
||||
Java version : ${System.getProperty("java.version")}
|
||||
@@ -63,5 +71,7 @@ Git Commit ID : ${buildInfo.commitId}
|
||||
====
|
||||
"""
|
||||
|
||||
val formattedMessage = message.replace("\n====", "\n" + "=".repeat(message.lines().maxByOrNull { it.length }!!.length))
|
||||
val formattedMessage =
|
||||
message.replace("\n====", "\n" + "=".repeat(message.lines().maxByOrNull { it.length }!!.length))
|
||||
|
||||
logger.info(formattedMessage)
|
||||
|
||||
@@ -1,15 +1,32 @@
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
`jvm-toolchains`
|
||||
}
|
||||
|
||||
// Keep this in sync with the constants in `BuildInfo.kt` (those are not addressable here).
|
||||
val toolchainVersion = 21
|
||||
|
||||
dependencies {
|
||||
implementation(libs.downloadTaskPlugin)
|
||||
implementation(libs.spotlessPlugin)
|
||||
implementation(libs.kotlinPlugin) {
|
||||
exclude(module = "kotlin-android-extensions")
|
||||
}
|
||||
implementation(libs.kotlinPlugin) { exclude(module = "kotlin-android-extensions") }
|
||||
implementation(libs.shadowPlugin)
|
||||
|
||||
// fix from the Gradle team: makes version catalog symbols available in build scripts
|
||||
@@ -18,16 +35,18 @@ dependencies {
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlin {
|
||||
target {
|
||||
compilations.configureEach {
|
||||
kotlinOptions {
|
||||
jvmTarget = "17"
|
||||
}
|
||||
}
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(toolchainVersion)
|
||||
vendor = JvmVendorSpec.ADOPTIUM
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile>().configureEach { options.release = toolchainVersion }
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(toolchainVersion)
|
||||
compilerOptions {
|
||||
jvmTarget = JvmTarget.fromTarget(toolchainVersion.toString())
|
||||
freeCompilerArgs.add("-Xjdk-release=$toolchainVersion")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@file:Suppress("UnstableApiUsage")
|
||||
|
||||
rootProject.name = "buildSrc"
|
||||
@@ -9,14 +24,12 @@ pluginManagement {
|
||||
}
|
||||
}
|
||||
|
||||
plugins { id("org.gradle.toolchains.foojay-resolver-convention") }
|
||||
|
||||
// makes ~/.gradle/init.gradle unnecessary and ~/.gradle/gradle.properties optional
|
||||
dependencyResolutionManagement {
|
||||
// use same version catalog as main build
|
||||
versionCatalogs {
|
||||
register("libs") {
|
||||
from(files("../gradle/libs.versions.toml"))
|
||||
}
|
||||
}
|
||||
versionCatalogs { register("libs") { from(files("../gradle/libs.versions.toml")) } }
|
||||
|
||||
repositories {
|
||||
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
|
||||
|
||||
@@ -1,26 +1,79 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@file:Suppress("MemberVisibilityCanBePrivate")
|
||||
|
||||
import java.io.File
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.VersionCatalog
|
||||
import org.gradle.api.artifacts.VersionCatalogsExtension
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
import org.gradle.api.attributes.Category
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import org.gradle.internal.extensions.stdlib.capitalized
|
||||
import org.gradle.jvm.toolchain.*
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.gradle.kotlin.dsl.support.serviceOf
|
||||
import org.gradle.process.CommandLineArgumentProvider
|
||||
|
||||
/**
|
||||
* JVM bytecode target; this is pinned at a reasonable version, because downstream JVM projects
|
||||
* which consume Pkl will need a minimum Bytecode level at or above this one.
|
||||
*
|
||||
* Kotlin and Java need matching bytecode targets, so this is expressed as a build setting and
|
||||
* constant default. To override, pass `-DpklJdkToolchain=X` to the Gradle command line, where X is
|
||||
* a major Java version.
|
||||
*/
|
||||
const val PKL_JVM_TARGET_DEFAULT_MAXIMUM = 17
|
||||
|
||||
/**
|
||||
* The Pkl build requires JDK 21+ to build, because JDK 17 is no longer within the default set of
|
||||
* supported JDKs for GraalVM. This is a build-time requirement, not a runtime requirement.
|
||||
*/
|
||||
const val PKL_JDK_VERSION_MIN = 21
|
||||
|
||||
/**
|
||||
* The JDK minimum is set to match the bytecode minimum, to guarantee that fat JARs work against the
|
||||
* earliest supported bytecode target.
|
||||
*/
|
||||
const val PKL_TEST_JDK_MINIMUM = PKL_JVM_TARGET_DEFAULT_MAXIMUM
|
||||
|
||||
/**
|
||||
* Maximum JDK version which Pkl is tested with; this should be bumped when new JDK stable releases
|
||||
* are issued. At the time of this writing, JDK 23 is the latest available release.
|
||||
*/
|
||||
const val PKL_TEST_JDK_MAXIMUM = 23
|
||||
|
||||
/**
|
||||
* Test the full suite of JDKs between [PKL_TEST_JDK_MINIMUM] and [PKL_TEST_JDK_MAXIMUM]; if this is
|
||||
* set to `false` (or overridden on the command line), only LTS releases are tested by default.
|
||||
*/
|
||||
const val PKL_TEST_ALL_JDKS = false
|
||||
|
||||
// `buildInfo` in main build scripts
|
||||
// `project.extensions.getByType<BuildInfo>()` in precompiled script plugins
|
||||
open class BuildInfo(project: Project) {
|
||||
open class BuildInfo(private val project: Project) {
|
||||
inner class GraalVm(val arch: String) {
|
||||
val homeDir: String by lazy {
|
||||
System.getenv("GRAALVM_HOME") ?: "${System.getProperty("user.home")}/.graalvm"
|
||||
}
|
||||
|
||||
val version: String by lazy {
|
||||
libs.findVersion("graalVm").get().toString()
|
||||
}
|
||||
val version: String by lazy { libs.findVersion("graalVm").get().toString() }
|
||||
|
||||
val graalVmJdkVersion: String by lazy {
|
||||
libs.findVersion("graalVmJdkVersion").get().toString()
|
||||
}
|
||||
val graalVmJdkVersion: String by lazy { libs.findVersion("graalVmJdkVersion").get().toString() }
|
||||
|
||||
val osName: String by lazy {
|
||||
when {
|
||||
@@ -31,9 +84,7 @@ open class BuildInfo(project: Project) {
|
||||
}
|
||||
}
|
||||
|
||||
val baseName: String by lazy {
|
||||
"graalvm-jdk-${graalVmJdkVersion}_${osName}-${arch}_bin"
|
||||
}
|
||||
val baseName: String by lazy { "graalvm-jdk-${graalVmJdkVersion}_${osName}-${arch}_bin" }
|
||||
|
||||
val downloadUrl: String by lazy {
|
||||
val jdkMajor = graalVmJdkVersion.takeWhile { it != '.' }
|
||||
@@ -41,18 +92,31 @@ open class BuildInfo(project: Project) {
|
||||
"https://download.oracle.com/graalvm/$jdkMajor/archive/$baseName.$extension"
|
||||
}
|
||||
|
||||
val installDir: File by lazy {
|
||||
File(homeDir, baseName)
|
||||
val downloadFile: File by lazy {
|
||||
val extension = if (os.isWindows) "zip" else "tar.gz"
|
||||
File(homeDir, "${baseName}.$extension")
|
||||
}
|
||||
|
||||
val installDir: File by lazy { File(homeDir, baseName) }
|
||||
|
||||
val baseDir: String by lazy {
|
||||
if (os.isMacOsX) "$installDir/Contents/Home" else installDir.toString()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Same logic as [org.gradle.internal.os.OperatingSystem#arch], which is protected.
|
||||
*/
|
||||
/** The target architecture to build, defaulting to the system architecture. */
|
||||
val targetArch by lazy { System.getProperty("pkl.targetArch") ?: arch }
|
||||
|
||||
/** Tells if this is a cross-arch build (e.g. targeting amd64 when on an aarch64 machine). */
|
||||
val isCrossArch by lazy { arch != targetArch }
|
||||
|
||||
/** Tells if cross-arch builds are supported on this machine. */
|
||||
val isCrossArchSupported by lazy { os.isMacOsX }
|
||||
|
||||
/** Whether to build native executables using the musl toolchain or not. */
|
||||
val musl: Boolean by lazy { java.lang.Boolean.getBoolean("pkl.musl") }
|
||||
|
||||
/** Same logic as [org.gradle.internal.os.OperatingSystem#arch], which is protected. */
|
||||
val arch: String by lazy {
|
||||
when (val arch = System.getProperty("os.arch")) {
|
||||
"x86" -> "i386"
|
||||
@@ -66,12 +130,212 @@ open class BuildInfo(project: Project) {
|
||||
|
||||
val graalVmAmd64: GraalVm = GraalVm("x64")
|
||||
|
||||
val isCiBuild: Boolean by lazy {
|
||||
System.getenv("CI") != null
|
||||
val isCiBuild: Boolean by lazy { System.getenv("CI") != null }
|
||||
|
||||
val isReleaseBuild: Boolean by lazy { java.lang.Boolean.getBoolean("releaseBuild") }
|
||||
|
||||
val isNativeArch: Boolean by lazy { java.lang.Boolean.getBoolean("nativeArch") }
|
||||
|
||||
val jvmTarget: Int by lazy {
|
||||
System.getProperty("pklJvmTarget")?.toInt() ?: PKL_JVM_TARGET_DEFAULT_MAXIMUM
|
||||
}
|
||||
|
||||
val isReleaseBuild: Boolean by lazy {
|
||||
java.lang.Boolean.getBoolean("releaseBuild")
|
||||
// JPMS exports for Truffle; needed on some versions of Java, and transitively within some JARs.
|
||||
private val jpmsExports =
|
||||
arrayOf(
|
||||
"org.graalvm.truffle/com.oracle.truffle.api.exception=ALL-UNNAMED",
|
||||
"org.graalvm.truffle/com.oracle.truffle.api=ALL-UNNAMED",
|
||||
"org.graalvm.truffle/com.oracle.truffle.api.nodes=ALL-UNNAMED",
|
||||
"org.graalvm.truffle/com.oracle.truffle.api.source=ALL-UNNAMED",
|
||||
)
|
||||
|
||||
// Extra JPMS modules forced onto the module path via `--add-modules` in some cases.
|
||||
private val jpmsAddModules = arrayOf("jdk.unsupported")
|
||||
|
||||
// Formats `jpmsExports` for use in JAR manifest attributes.
|
||||
val jpmsExportsForJarManifest: String by lazy {
|
||||
jpmsExports.joinToString(" ") { it.substringBefore("=") }
|
||||
}
|
||||
|
||||
// Formats `jpmsExports` for use on the command line with `--add-exports`.
|
||||
val jpmsExportsForAddExportsFlags: Collection<String> by lazy {
|
||||
jpmsExports.map { "--add-exports=$it" }
|
||||
}
|
||||
|
||||
// Formats `jpmsAddModules` for use on the command line with `--add-modules`.
|
||||
val jpmsAddModulesFlags: Collection<String> by lazy { jpmsAddModules.map { "--add-modules=$it" } }
|
||||
|
||||
// JVM properties to set during testing.
|
||||
val testProperties =
|
||||
mapOf<String, Any>(
|
||||
// @TODO: this should be removed once pkl supports JPMS as a true Java Module.
|
||||
"polyglotimpl.DisableClassPathIsolation" to true
|
||||
)
|
||||
|
||||
val jdkVendor: JvmVendorSpec = JvmVendorSpec.ADOPTIUM
|
||||
|
||||
val jdkToolchainVersion: JavaLanguageVersion by lazy {
|
||||
JavaLanguageVersion.of(System.getProperty("pklJdkToolchain")?.toInt() ?: PKL_JDK_VERSION_MIN)
|
||||
}
|
||||
|
||||
val jdkTestFloor: JavaLanguageVersion by lazy { JavaLanguageVersion.of(PKL_TEST_JDK_MINIMUM) }
|
||||
|
||||
val jdkTestCeiling: JavaLanguageVersion by lazy { JavaLanguageVersion.of(PKL_TEST_JDK_MAXIMUM) }
|
||||
|
||||
val testAllJdks: Boolean by lazy {
|
||||
// By default, Pkl is tested against LTS JDK releases within the bounds of `PKL_TEST_JDK_TARGET`
|
||||
// and `PKL_TEST_JDK_MAXIMUM`. To test against the full suite of JDK versions, past and present,
|
||||
// set `-DpklTestAllJdks=true` on the Gradle command line. This results in non-LTS releases, old
|
||||
// releases, and "experimental releases" (newer than the toolchain version) being included in
|
||||
// the default `check` suite.
|
||||
System.getProperty("pklTestAllJdks")?.toBoolean() ?: PKL_TEST_ALL_JDKS
|
||||
}
|
||||
|
||||
val testExperimentalJdks: Boolean by lazy {
|
||||
System.getProperty("pklTestFutureJdks")?.toBoolean() ?: false
|
||||
}
|
||||
|
||||
val testJdkVendors: Sequence<JvmVendorSpec> by lazy {
|
||||
// By default, only OpenJDK is tested during multi-JDK testing. Flip `-DpklTestAllVendors=true`
|
||||
// to additionally test against a suite of JDK vendors, including Azul, Oracle, and GraalVM.
|
||||
when (System.getProperty("pklTestAllVendors")?.toBoolean()) {
|
||||
true -> sequenceOf(JvmVendorSpec.ADOPTIUM, JvmVendorSpec.GRAAL_VM, JvmVendorSpec.ORACLE)
|
||||
else -> sequenceOf(JvmVendorSpec.ADOPTIUM)
|
||||
}
|
||||
}
|
||||
|
||||
// Assembles a collection of JDK versions which tests can be run against, considering ancillary
|
||||
// parameters like `testAllJdks` and `testExperimentalJdks`.
|
||||
val jdkTestRange: Collection<JavaLanguageVersion> by lazy {
|
||||
JavaVersionRange.inclusive(jdkTestFloor, jdkTestCeiling).toList()
|
||||
}
|
||||
|
||||
val JavaLanguageVersion.isEnabled: Boolean
|
||||
get() = isVersionEnabled(this)
|
||||
|
||||
fun isVersionEnabled(version: JavaLanguageVersion): Boolean {
|
||||
return when {
|
||||
testAllJdks -> true
|
||||
multiJdkTesting -> JavaVersionRange.isLTS(version)
|
||||
testExperimentalJdks -> version > jdkToolchainVersion
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun JavaToolchainSpec.pklJdkToolchain() {
|
||||
languageVersion.set(jdkToolchainVersion)
|
||||
vendor.set(jdkVendor)
|
||||
}
|
||||
|
||||
private fun labelForVendor(vendor: JvmVendorSpec): String =
|
||||
when (vendor) {
|
||||
JvmVendorSpec.AZUL -> "Zulu"
|
||||
JvmVendorSpec.GRAAL_VM -> "GraalVm"
|
||||
JvmVendorSpec.ORACLE -> "Oracle"
|
||||
JvmVendorSpec.ADOPTIUM -> "Adoptium"
|
||||
else -> error("Unrecognized JDK vendor: $vendor")
|
||||
}
|
||||
|
||||
private fun testNamer(baseName: () -> String): (JavaLanguageVersion, JvmVendorSpec?) -> String =
|
||||
{ jdkTarget, vendor ->
|
||||
val targetToken =
|
||||
when (vendor) {
|
||||
null -> "Jdk${jdkTarget.asInt()}"
|
||||
else -> "Jdk${jdkTarget.asInt()}${labelForVendor(vendor).capitalized()}"
|
||||
}
|
||||
if (jdkTarget > jdkToolchainVersion) {
|
||||
// test targets above the toolchain target are considered "experimental".
|
||||
"${baseName()}${targetToken}Experimental"
|
||||
} else {
|
||||
"${baseName()}${targetToken}"
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
fun multiJdkTestingWith(
|
||||
templateTask: TaskProvider<out Test>,
|
||||
configurator: MultiJdkTestConfigurator = {},
|
||||
): Iterable<Provider<out Any>> =
|
||||
with(project) {
|
||||
val isMultiVendor = testJdkVendors.count() > 1
|
||||
val baseNameProvider = { templateTask.get().name }
|
||||
val namer = testNamer(baseNameProvider)
|
||||
val applyConfig: MultiJdkTestConfigurator = { (version, jdk) ->
|
||||
// 1) copy configurations from the template task
|
||||
dependsOn(templateTask)
|
||||
templateTask.get().let { template ->
|
||||
classpath = template.classpath
|
||||
testClassesDirs = template.testClassesDirs
|
||||
jvmArgs.addAll(template.jvmArgs)
|
||||
jvmArgumentProviders.addAll(template.jvmArgumentProviders)
|
||||
forkEvery = template.forkEvery
|
||||
maxParallelForks = template.maxParallelForks
|
||||
minHeapSize = template.minHeapSize
|
||||
maxHeapSize = template.maxHeapSize
|
||||
exclude(template.excludes)
|
||||
template.systemProperties.forEach { prop -> systemProperty(prop.key, prop.value) }
|
||||
}
|
||||
|
||||
// 2) assign launcher
|
||||
javaLauncher = jdk
|
||||
|
||||
// 3) dispatch the user's configurator
|
||||
configurator(version to jdk)
|
||||
}
|
||||
|
||||
serviceOf<JavaToolchainService>().let { toolchains ->
|
||||
jdkTestRange
|
||||
.flatMap { targetVersion ->
|
||||
// multiply out by jdk vendor
|
||||
testJdkVendors.map { vendor -> (targetVersion to vendor) }
|
||||
}
|
||||
.map { (jdkTarget, vendor) ->
|
||||
if (jdkToolchainVersion == jdkTarget)
|
||||
tasks.register(namer(jdkTarget, vendor)) {
|
||||
// alias to `test`
|
||||
dependsOn(templateTask)
|
||||
group = Category.VERIFICATION
|
||||
description =
|
||||
"Alias for regular '${baseNameProvider()}' task, on JDK ${jdkTarget.asInt()}"
|
||||
}
|
||||
else
|
||||
tasks.register(namer(jdkTarget, vendor.takeIf { isMultiVendor }), Test::class) {
|
||||
enabled = jdkTarget.isEnabled
|
||||
group = Category.VERIFICATION
|
||||
description = "Run tests against JDK ${jdkTarget.asInt()}"
|
||||
applyConfig(jdkTarget to toolchains.launcherFor { languageVersion = jdkTarget })
|
||||
// fix: on jdk17, we must force the polyglot module on to the modulepath
|
||||
if (jdkTarget.asInt() == 17)
|
||||
jvmArgumentProviders.add(
|
||||
CommandLineArgumentProvider {
|
||||
buildList { listOf("--add-modules=org.graalvm.polyglot") }
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
}
|
||||
|
||||
val javaCompiler: Provider<JavaCompiler> by lazy {
|
||||
project.serviceOf<JavaToolchainService>().let { toolchainService ->
|
||||
toolchainService.compilerFor { pklJdkToolchain() }
|
||||
}
|
||||
}
|
||||
|
||||
val javaTestLauncher: Provider<JavaLauncher> by lazy {
|
||||
project.serviceOf<JavaToolchainService>().let { toolchainService ->
|
||||
toolchainService.launcherFor { pklJdkToolchain() }
|
||||
}
|
||||
}
|
||||
|
||||
val multiJdkTesting: Boolean by lazy {
|
||||
// Test Pkl against a full range of JDK versions, past and present, within the
|
||||
// supported bounds of `PKL_TEST_JDK_TARGET` and `PKL_TEST_JDK_MAXIMUM`.
|
||||
//
|
||||
// In CI, this defaults to `true` to catch potential cross-JDK compat regressions or other bugs.
|
||||
// In local dev, this defaults to `false` to speed up the build and reduce contributor load.
|
||||
System.getProperty("pklMultiJdkTesting")?.toBoolean() ?: isCiBuild
|
||||
}
|
||||
|
||||
val hasMuslToolchain: Boolean by lazy {
|
||||
@@ -85,12 +349,15 @@ open class BuildInfo(project: Project) {
|
||||
|
||||
// could be `commitId: Provider<String> = project.provider { ... }`
|
||||
val commitId: String by lazy {
|
||||
// allow -DcommitId=abc123 for build environments that don't have git.
|
||||
System.getProperty("commitId").let { if (it != null) return@lazy it }
|
||||
// only run command once per build invocation
|
||||
if (project === project.rootProject) {
|
||||
val process = ProcessBuilder()
|
||||
.command("git", "rev-parse", "--short", "HEAD")
|
||||
.directory(project.rootDir)
|
||||
.start()
|
||||
val process =
|
||||
ProcessBuilder()
|
||||
.command("git", "rev-parse", "--short", "HEAD")
|
||||
.directory(project.rootDir)
|
||||
.start()
|
||||
process.waitFor().also { exitCode ->
|
||||
if (exitCode == -1) throw RuntimeException(process.errorStream.reader().readText())
|
||||
}
|
||||
@@ -100,9 +367,7 @@ open class BuildInfo(project: Project) {
|
||||
}
|
||||
}
|
||||
|
||||
val commitish: String by lazy {
|
||||
if (isReleaseBuild) project.version.toString() else commitId
|
||||
}
|
||||
val commitish: String by lazy { if (isReleaseBuild) project.version.toString() else commitId }
|
||||
|
||||
val pklVersion: String by lazy {
|
||||
if (isReleaseBuild) {
|
||||
@@ -131,3 +396,7 @@ open class BuildInfo(project: Project) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shape of a function which is applied to configure multi-JDK testing.
|
||||
private typealias MultiJdkTestConfigurator =
|
||||
Test.(Pair<JavaLanguageVersion, Provider<JavaLauncher>>) -> Unit
|
||||
|
||||
@@ -1,39 +1,66 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
/**
|
||||
* Builds a self-contained Pkl CLI Jar that is directly executable on *nix
|
||||
* and executable with `java -jar` on Windows.
|
||||
* Builds a self-contained Pkl CLI Jar that is directly executable on Windows, macOS, and Linux.
|
||||
*
|
||||
* For direct execution, the `java` command must be on the PATH.
|
||||
*
|
||||
* https://skife.org/java/unix/2011/06/20/really_executable_jars.html
|
||||
* Technique borrowed from [Mill](https://mill-build.org/blog/5-executable-jars.html).
|
||||
*/
|
||||
abstract class ExecutableJar : DefaultTask() {
|
||||
@get:InputFile
|
||||
abstract val inJar: RegularFileProperty
|
||||
@get:InputFile abstract val inJar: RegularFileProperty
|
||||
|
||||
@get:OutputFile
|
||||
abstract val outJar: RegularFileProperty
|
||||
@get:OutputFile abstract val outJar: RegularFileProperty
|
||||
|
||||
@get:Input
|
||||
abstract val jvmArgs: ListProperty<String>
|
||||
@get:Input abstract val jvmArgs: ListProperty<String>
|
||||
|
||||
@TaskAction
|
||||
fun buildJar() {
|
||||
val inFile = inJar.get().asFile
|
||||
val outFile = outJar.get().asFile
|
||||
val escapedJvmArgs = jvmArgs.get().joinToString(separator = " ") { "\"$it\"" }
|
||||
val startScript = """
|
||||
#!/bin/sh
|
||||
exec java $escapedJvmArgs -jar $0 "$@"
|
||||
""".trimIndent() + "\n\n\n"
|
||||
val unixStartScript =
|
||||
"""
|
||||
@ 2>/dev/null # 2>nul & echo off & goto BOF
|
||||
:
|
||||
exec java $escapedJvmArgs -jar "$0" "$@"
|
||||
exit
|
||||
"""
|
||||
.trimIndent()
|
||||
val windowsStartScript =
|
||||
"""
|
||||
:BOF
|
||||
setlocal
|
||||
@echo off
|
||||
java $escapedJvmArgs -jar "%~dpnx0" %*
|
||||
endlocal
|
||||
exit /B %errorlevel%
|
||||
"""
|
||||
.trimIndent()
|
||||
// need crlf endings for Windows portion of script
|
||||
.replace("\n", "\r\n")
|
||||
val startScript = unixStartScript + "\r\n" + windowsStartScript + "\r\n".repeat(3)
|
||||
outFile.outputStream().use { outStream ->
|
||||
startScript.byteInputStream().use { it.copyTo(outStream) }
|
||||
inFile.inputStream().use { it.copyTo(outStream) }
|
||||
|
||||
49
buildSrc/src/main/kotlin/ExecutableSpec.kt
Normal file
49
buildSrc/src/main/kotlin/ExecutableSpec.kt
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import org.gradle.api.provider.Property
|
||||
|
||||
abstract class ExecutableSpec {
|
||||
/** The main entrypoint Java class of the executable. */
|
||||
abstract val mainClass: Property<String>
|
||||
|
||||
/**
|
||||
* The name of the native executable.
|
||||
*
|
||||
* Not required if not building a native executable.
|
||||
*/
|
||||
abstract val name: Property<String>
|
||||
|
||||
/** The name of the Java executable. */
|
||||
abstract val javaName: Property<String>
|
||||
|
||||
/** The name of the executable that shows in the description when published to Maven. */
|
||||
abstract val documentationName: Property<String>
|
||||
|
||||
/**
|
||||
* The base name of the Maven publication.
|
||||
*
|
||||
* This becomes the base name of the Artifact ID, with the os and arch suffixed.
|
||||
*
|
||||
* For example, `pkl` becomes `pkl-macos-aarch` for the macOS/aarch64 variant.
|
||||
*/
|
||||
abstract val publicationName: Property<String>
|
||||
|
||||
/** The name of the artifact ID for the Java executable. */
|
||||
abstract val javaPublicationName: Property<String>
|
||||
|
||||
/** The website for this executable. */
|
||||
abstract val website: Property<String>
|
||||
}
|
||||
@@ -1,7 +1,22 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import org.gradle.util.GradleVersion
|
||||
|
||||
open class GradlePluginTests {
|
||||
lateinit var minGradleVersion: GradleVersion
|
||||
lateinit var maxGradleVersion: GradleVersion
|
||||
var skippedGradleVersions: List<GradleVersion> = listOf()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
import org.gradle.util.GradleVersion
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import groovy.json.JsonSlurper
|
||||
import java.net.URI
|
||||
import org.gradle.util.GradleVersion
|
||||
|
||||
@Suppress("unused")
|
||||
class GradleVersionInfo(json: Map<String, Any>) {
|
||||
@@ -38,15 +53,19 @@ class GradleVersionInfo(json: Map<String, Any>) {
|
||||
val wrapperChecksumUrl: String by json
|
||||
|
||||
companion object {
|
||||
private fun fetchAll(): List<GradleVersionInfo> = fetchMultiple("https://services.gradle.org/versions/all")
|
||||
private fun fetchAll(): List<GradleVersionInfo> =
|
||||
fetchMultiple("https://services.gradle.org/versions/all")
|
||||
|
||||
fun fetchReleases(): List<GradleVersionInfo> = fetchAll().filter { it.isReleaseVersion }
|
||||
|
||||
fun fetchCurrent(): GradleVersionInfo = fetchSingle("https://services.gradle.org/versions/current")
|
||||
fun fetchCurrent(): GradleVersionInfo =
|
||||
fetchSingle("https://services.gradle.org/versions/current")
|
||||
|
||||
fun fetchRc(): GradleVersionInfo? = fetchSingleOrNull("https://services.gradle.org/versions/release-candidate")
|
||||
fun fetchRc(): GradleVersionInfo? =
|
||||
fetchSingleOrNull("https://services.gradle.org/versions/release-candidate")
|
||||
|
||||
fun fetchNightly(): GradleVersionInfo = fetchSingle("https://services.gradle.org/versions/nightly")
|
||||
fun fetchNightly(): GradleVersionInfo =
|
||||
fetchSingle("https://services.gradle.org/versions/nightly")
|
||||
|
||||
private fun fetchSingle(url: String): GradleVersionInfo {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@@ -61,8 +80,9 @@ class GradleVersionInfo(json: Map<String, Any>) {
|
||||
|
||||
private fun fetchMultiple(url: String): List<GradleVersionInfo> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return (JsonSlurper().parse(URI(url).toURL()) as List<Map<String, Any>>)
|
||||
.map { GradleVersionInfo(it) }
|
||||
return (JsonSlurper().parse(URI(url).toURL()) as List<Map<String, Any>>).map {
|
||||
GradleVersionInfo(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
|
||||
open class HtmlValidator(project: Project) {
|
||||
var sources: FileCollection = project.files()
|
||||
}
|
||||
}
|
||||
|
||||
91
buildSrc/src/main/kotlin/InstallGraalVm.kt
Normal file
91
buildSrc/src/main/kotlin/InstallGraalVm.kt
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
import java.nio.file.StandardCopyOption
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.io.path.createDirectories
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.internal.file.FileOperations
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.process.ExecOperations
|
||||
|
||||
abstract class InstallGraalVm
|
||||
@Inject
|
||||
constructor(
|
||||
private val fileOperations: FileOperations,
|
||||
private val execOperations: ExecOperations,
|
||||
) : DefaultTask() {
|
||||
@get:Input abstract val graalVm: Property<BuildInfo.GraalVm>
|
||||
|
||||
init {
|
||||
@Suppress("LeakingThis") onlyIf("GraalVM not installed") { !graalVm.get().installDir.exists() }
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
@Suppress("unused")
|
||||
fun run() {
|
||||
// minimize chance of corruption by extract-to-random-dir-and-flip-symlink
|
||||
val distroDir = Paths.get(graalVm.get().homeDir, UUID.randomUUID().toString())
|
||||
try {
|
||||
distroDir.createDirectories()
|
||||
println("Extracting ${graalVm.get().downloadFile} into $distroDir")
|
||||
// faster and more reliable than Gradle's `copy { from tarTree() }`
|
||||
execOperations.exec {
|
||||
workingDir = distroDir.toFile()
|
||||
executable = "tar"
|
||||
args("--strip-components=1", "-xzf", graalVm.get().downloadFile)
|
||||
}
|
||||
|
||||
val os = org.gradle.internal.os.OperatingSystem.current()
|
||||
val distroBinDir =
|
||||
if (os.isMacOsX) distroDir.resolve("Contents/Home/bin") else distroDir.resolve("bin")
|
||||
|
||||
println("Installing native-image into $distroDir")
|
||||
val gvmVersionMajor =
|
||||
requireNotNull(graalVm.get().version.split(".").first().toIntOrNull()) {
|
||||
"Invalid GraalVM JDK version: ${graalVm.get().graalVmJdkVersion}"
|
||||
}
|
||||
if (gvmVersionMajor < 24) {
|
||||
execOperations.exec {
|
||||
val executableName = if (os.isWindows) "gu.cmd" else "gu"
|
||||
executable = distroBinDir.resolve(executableName).toString()
|
||||
args("install", "--no-progress", "native-image")
|
||||
}
|
||||
}
|
||||
|
||||
println("Creating symlink ${graalVm.get().installDir} for $distroDir")
|
||||
val tempLink = Paths.get(graalVm.get().homeDir, UUID.randomUUID().toString())
|
||||
Files.createSymbolicLink(tempLink, distroDir)
|
||||
try {
|
||||
Files.move(tempLink, graalVm.get().installDir.toPath(), StandardCopyOption.ATOMIC_MOVE)
|
||||
} catch (e: Exception) {
|
||||
try {
|
||||
fileOperations.delete(tempLink.toFile())
|
||||
} catch (ignored: Exception) {}
|
||||
throw e
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
try {
|
||||
fileOperations.delete(distroDir)
|
||||
} catch (ignored: Exception) {}
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
64
buildSrc/src/main/kotlin/JavaVersionRange.kt
Normal file
64
buildSrc/src/main/kotlin/JavaVersionRange.kt
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@file:Suppress("MemberVisibilityCanBePrivate")
|
||||
|
||||
import java.util.*
|
||||
import org.gradle.jvm.toolchain.JavaLanguageVersion
|
||||
|
||||
typealias JavaVersionPair = Pair<JavaLanguageVersion, JavaLanguageVersion>
|
||||
|
||||
// All LTS releases.
|
||||
private val ltsReleases =
|
||||
sortedSetOf(
|
||||
JavaLanguageVersion.of(8),
|
||||
JavaLanguageVersion.of(11),
|
||||
JavaLanguageVersion.of(17),
|
||||
JavaLanguageVersion.of(21),
|
||||
)
|
||||
|
||||
/** Describes an inclusive range of JVM versions, based on the [JavaLanguageVersion] type. */
|
||||
@JvmInline
|
||||
value class JavaVersionRange private constructor(private val bounds: JavaVersionPair) :
|
||||
Iterable<JavaLanguageVersion> {
|
||||
@Suppress("unused")
|
||||
companion object {
|
||||
fun isLTS(version: JavaLanguageVersion): Boolean = version in ltsReleases
|
||||
|
||||
fun inclusive(floor: JavaLanguageVersion, ceiling: JavaLanguageVersion): JavaVersionRange =
|
||||
JavaVersionRange(floor to ceiling)
|
||||
|
||||
fun startingAt(floor: JavaLanguageVersion): JavaVersionRange =
|
||||
inclusive(floor, JavaLanguageVersion.of(PKL_TEST_JDK_MAXIMUM))
|
||||
|
||||
fun upTo(ceiling: JavaLanguageVersion): JavaVersionRange =
|
||||
inclusive(JavaLanguageVersion.of(PKL_TEST_JDK_MINIMUM), ceiling)
|
||||
}
|
||||
|
||||
operator fun contains(version: JavaLanguageVersion): Boolean =
|
||||
version >= bounds.first && version <= bounds.second
|
||||
|
||||
fun asSequence(): Sequence<JavaLanguageVersion> = sequence {
|
||||
var current = bounds.first
|
||||
while (current <= bounds.second) {
|
||||
yield(current)
|
||||
current = JavaLanguageVersion.of(current.asInt() + 1)
|
||||
}
|
||||
}
|
||||
|
||||
fun asSortedSet(): SortedSet<JavaLanguageVersion> = asSequence().toSortedSet()
|
||||
|
||||
override fun iterator(): Iterator<JavaLanguageVersion> = asSortedSet().iterator()
|
||||
}
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import java.io.File
|
||||
import java.util.regex.Matcher
|
||||
import java.util.regex.Pattern
|
||||
@@ -15,21 +30,18 @@ import org.gradle.kotlin.dsl.listProperty
|
||||
import org.gradle.kotlin.dsl.mapProperty
|
||||
|
||||
open class MergeSourcesJars : DefaultTask() {
|
||||
@get:InputFiles
|
||||
val inputJars: ConfigurableFileCollection = project.objects.fileCollection()
|
||||
@get:InputFiles val inputJars: ConfigurableFileCollection = project.objects.fileCollection()
|
||||
|
||||
@get:InputFiles
|
||||
val mergedBinaryJars: ConfigurableFileCollection = project.objects.fileCollection()
|
||||
|
||||
@get:Input
|
||||
val relocatedPackages: MapProperty<String, String> = project.objects.mapProperty()
|
||||
@get:Input val relocatedPackages: MapProperty<String, String> = project.objects.mapProperty()
|
||||
|
||||
@get:Input
|
||||
var sourceFileExtensions: ListProperty<String> = project.objects.listProperty<String>()
|
||||
.convention(listOf(".java", ".kt"))
|
||||
var sourceFileExtensions: ListProperty<String> =
|
||||
project.objects.listProperty<String>().convention(listOf(".java", ".kt"))
|
||||
|
||||
@get:OutputFile
|
||||
val outputJar: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:OutputFile val outputJar: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@TaskAction
|
||||
@Suppress("unused")
|
||||
@@ -38,12 +50,15 @@ open class MergeSourcesJars : DefaultTask() {
|
||||
|
||||
val relocatedPkgs = relocatedPackages.get()
|
||||
|
||||
val relocatedPaths = relocatedPkgs.entries.associate { (key, value) -> toPath(key) to toPath(value) }
|
||||
val relocatedPaths =
|
||||
relocatedPkgs.entries.associate { (key, value) -> toPath(key) to toPath(value) }
|
||||
|
||||
// use negative lookbehind to match any that don't precede with
|
||||
// a word or a period character. should catch most cases.
|
||||
val importPattern = Pattern.compile("(?<!(\\w|\\.))(" +
|
||||
relocatedPkgs.keys.joinToString("|") { it.replace(".", "\\.") } + ")")
|
||||
val importPattern =
|
||||
Pattern.compile(
|
||||
"(?<!(\\w|\\.))(" + relocatedPkgs.keys.joinToString("|") { it.replace(".", "\\.") } + ")"
|
||||
)
|
||||
|
||||
val sourceFileExts = sourceFileExtensions.get()
|
||||
|
||||
@@ -96,7 +111,7 @@ open class MergeSourcesJars : DefaultTask() {
|
||||
relocatedPkgs: Map<String, String>,
|
||||
details: FileVisitDetails,
|
||||
sourceText: String,
|
||||
importPattern: Pattern
|
||||
importPattern: Pattern,
|
||||
): String {
|
||||
val matcher = importPattern.matcher(sourceText)
|
||||
val buffer = StringBuffer()
|
||||
|
||||
169
buildSrc/src/main/kotlin/NativeImageBuild.kt
Normal file
169
buildSrc/src/main/kotlin/NativeImageBuild.kt
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import javax.inject.Inject
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.services.BuildService
|
||||
import org.gradle.api.services.BuildServiceParameters
|
||||
import org.gradle.api.tasks.ClasspathNormalizer
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.PathSensitivity
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.registerIfAbsent
|
||||
import org.gradle.kotlin.dsl.withNormalizer
|
||||
import org.gradle.process.ExecOperations
|
||||
|
||||
enum class Architecture {
|
||||
AMD64,
|
||||
AARCH64,
|
||||
}
|
||||
|
||||
abstract class NativeImageBuildService : BuildService<BuildServiceParameters.None>
|
||||
|
||||
abstract class NativeImageBuild : DefaultTask() {
|
||||
@get:Input abstract val imageName: Property<String>
|
||||
|
||||
@get:Input abstract val extraNativeImageArgs: ListProperty<String>
|
||||
|
||||
@get:Input abstract val arch: Property<Architecture>
|
||||
|
||||
@get:Input abstract val mainClass: Property<String>
|
||||
|
||||
@get:InputFiles abstract val classpath: ConfigurableFileCollection
|
||||
|
||||
private val outputDir = project.layout.buildDirectory.dir("executable")
|
||||
|
||||
@get:OutputFile val outputFile = outputDir.flatMap { it.file(imageName) }
|
||||
|
||||
@get:Inject protected abstract val execOperations: ExecOperations
|
||||
|
||||
private val graalVm: Provider<BuildInfo.GraalVm> =
|
||||
arch.map { a ->
|
||||
when (a) {
|
||||
Architecture.AMD64 -> buildInfo.graalVmAmd64
|
||||
Architecture.AARCH64 -> buildInfo.graalVmAarch64
|
||||
}
|
||||
}
|
||||
|
||||
private val buildInfo: BuildInfo = project.extensions.getByType(BuildInfo::class.java)
|
||||
|
||||
private val nativeImageCommandName =
|
||||
if (buildInfo.os.isWindows) "native-image.cmd" else "native-image"
|
||||
|
||||
private val nativeImageExecutable = graalVm.map { "${it.baseDir}/bin/$nativeImageCommandName" }
|
||||
|
||||
private val extraArgsFromProperties by lazy {
|
||||
System.getProperties()
|
||||
.filter { it.key.toString().startsWith("pkl.native") }
|
||||
.map { "${it.key}=${it.value}".substring("pkl.native".length) }
|
||||
}
|
||||
|
||||
private val buildService =
|
||||
project.gradle.sharedServices.registerIfAbsent(
|
||||
"nativeImageBuildService",
|
||||
NativeImageBuildService::class,
|
||||
) {
|
||||
maxParallelUsages.set(1)
|
||||
}
|
||||
|
||||
init {
|
||||
// ensure native-image builds run in serial (prevent `gw buildNative` from consuming all host
|
||||
// CPU resources).
|
||||
usesService(buildService)
|
||||
|
||||
group = "build"
|
||||
|
||||
inputs
|
||||
.files(classpath)
|
||||
.withPropertyName("runtimeClasspath")
|
||||
.withNormalizer(ClasspathNormalizer::class)
|
||||
inputs
|
||||
.files(nativeImageExecutable)
|
||||
.withPropertyName("graalVmNativeImage")
|
||||
.withPathSensitivity(PathSensitivity.ABSOLUTE)
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
protected fun run() {
|
||||
execOperations.exec {
|
||||
val exclusions =
|
||||
listOf(buildInfo.libs.findLibrary("graalSdk").get()).map { it.get().module.name }
|
||||
|
||||
executable = nativeImageExecutable.get()
|
||||
workingDir(outputDir)
|
||||
|
||||
args = buildList {
|
||||
// must be emitted before any experimental options are used
|
||||
add("-H:+UnlockExperimentalVMOptions")
|
||||
// currently gives a deprecation warning, but we've been told
|
||||
// that the "initialize everything at build time" *CLI* option is likely here to stay
|
||||
add("--initialize-at-build-time=")
|
||||
// needed for messagepack-java (see https://github.com/msgpack/msgpack-java/issues/600)
|
||||
add("--initialize-at-run-time=org.msgpack.core.buffer.DirectBufferAccess")
|
||||
add("--no-fallback")
|
||||
add("-H:IncludeResources=org/pkl/core/stdlib/.*\\.pkl")
|
||||
add("-H:IncludeResources=org/jline/utils/.*")
|
||||
add("-H:IncludeResourceBundles=org.pkl.core.errorMessages")
|
||||
add("-H:IncludeResourceBundles=org.pkl.parser.errorMessages")
|
||||
add("-H:IncludeResources=org/pkl/commons/cli/PklCARoots.pem")
|
||||
add("-H:Class=${mainClass.get()}")
|
||||
add("-o")
|
||||
add(imageName.get())
|
||||
// the actual limit (currently) used by native-image is this number + 1400 (idea is to
|
||||
// compensate for Truffle's own nodes)
|
||||
add("-H:MaxRuntimeCompileMethods=1800")
|
||||
add("-H:+EnforceMaxRuntimeCompileMethods")
|
||||
add("--enable-url-protocols=http,https")
|
||||
add("-H:+ReportExceptionStackTraces")
|
||||
// disable automatic support for JVM CLI options (puts our main class in full control of
|
||||
// argument parsing)
|
||||
add("-H:-ParseRuntimeOptions")
|
||||
// quick build mode: 40% faster compilation, 20% smaller (but presumably also slower)
|
||||
// executable
|
||||
if (!buildInfo.isReleaseBuild) {
|
||||
add("-Ob")
|
||||
}
|
||||
if (buildInfo.isNativeArch) {
|
||||
add("-march=native")
|
||||
} else {
|
||||
add("-march=compatibility")
|
||||
}
|
||||
// native-image rejects non-existing class path entries -> filter
|
||||
add("--class-path")
|
||||
val pathInput =
|
||||
classpath.filter {
|
||||
it.exists() && !exclusions.any { exclude -> it.name.contains(exclude) }
|
||||
}
|
||||
add(pathInput.asPath)
|
||||
// make sure dev machine stays responsive (15% slowdown on my laptop)
|
||||
val processors =
|
||||
Runtime.getRuntime().availableProcessors() /
|
||||
if (buildInfo.os.isMacOsX && !buildInfo.isCiBuild) 4 else 1
|
||||
add("-J-XX:ActiveProcessorCount=${processors}")
|
||||
// Pass through all `HOMEBREW_` prefixed environment variables to allow build with shimmed
|
||||
// tools.
|
||||
addAll(environment.keys.filter { it.startsWith("HOMEBREW_") }.map { "-E$it" })
|
||||
addAll(extraNativeImageArgs.get())
|
||||
addAll(extraArgsFromProperties)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.result.ResolvedArtifactResult
|
||||
@@ -12,27 +27,29 @@ import org.gradle.kotlin.dsl.property
|
||||
import org.gradle.language.base.artifact.SourcesArtifact
|
||||
|
||||
open class ResolveSourcesJars : DefaultTask() {
|
||||
@get:InputFiles
|
||||
val configuration: Property<Configuration> = project.objects.property()
|
||||
@get:InputFiles val configuration: Property<Configuration> = project.objects.property()
|
||||
|
||||
@get:OutputDirectory
|
||||
val outputDir: DirectoryProperty = project.objects.directoryProperty()
|
||||
@get:OutputDirectory val outputDir: DirectoryProperty = project.objects.directoryProperty()
|
||||
|
||||
@TaskAction
|
||||
@Suppress("UnstableApiUsage", "unused")
|
||||
fun resolve() {
|
||||
val componentIds = configuration.get().incoming.resolutionResult.allDependencies.map {
|
||||
(it as ResolvedDependencyResult).selected.id
|
||||
}
|
||||
val componentIds =
|
||||
configuration.get().incoming.resolutionResult.allDependencies.map {
|
||||
(it as ResolvedDependencyResult).selected.id
|
||||
}
|
||||
|
||||
val resolutionResult = project.dependencies.createArtifactResolutionQuery()
|
||||
.forComponents(componentIds)
|
||||
.withArtifacts(JvmLibrary::class.java, SourcesArtifact::class.java)
|
||||
.execute()
|
||||
val resolutionResult =
|
||||
project.dependencies
|
||||
.createArtifactResolutionQuery()
|
||||
.forComponents(componentIds)
|
||||
.withArtifacts(JvmLibrary::class.java, SourcesArtifact::class.java)
|
||||
.execute()
|
||||
|
||||
val resolvedJars = resolutionResult.resolvedComponents
|
||||
.flatMap { it.getArtifacts(SourcesArtifact::class.java) }
|
||||
.map { (it as ResolvedArtifactResult).file }
|
||||
val resolvedJars =
|
||||
resolutionResult.resolvedComponents
|
||||
.flatMap { it.getArtifacts(SourcesArtifact::class.java) }
|
||||
.map { (it as ResolvedArtifactResult).file }
|
||||
|
||||
// copying to an output dir because I don't know how else to describe task outputs
|
||||
project.sync {
|
||||
|
||||
@@ -1,10 +1,28 @@
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import com.diffplug.gradle.spotless.KotlinGradleExtension
|
||||
import org.gradle.accessors.dm.LibrariesForLibs
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
|
||||
|
||||
plugins { id("com.diffplug.spotless") }
|
||||
|
||||
val buildInfo = extensions.create<BuildInfo>("buildInfo", project)
|
||||
|
||||
dependencyLocking {
|
||||
lockAllConfigurations()
|
||||
}
|
||||
dependencyLocking { lockAllConfigurations() }
|
||||
|
||||
configurations {
|
||||
val rejectedVersionSuffix = Regex("-alpha|-beta|-eap|-m|-rc|-snapshot", RegexOption.IGNORE_CASE)
|
||||
@@ -13,8 +31,10 @@ configurations {
|
||||
componentSelection {
|
||||
all {
|
||||
if (rejectedVersionSuffix.containsMatchIn(candidate.version)) {
|
||||
reject("Rejected dependency $candidate " +
|
||||
"because it has a prelease version suffix matching `$rejectedVersionSuffix`.")
|
||||
reject(
|
||||
"Rejected dependency $candidate " +
|
||||
"because it has a prelease version suffix matching `$rejectedVersionSuffix`."
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,38 +42,35 @@ configurations {
|
||||
}
|
||||
}
|
||||
|
||||
plugins.withType(JavaPlugin::class).configureEach {
|
||||
val java = project.extensions.getByType<JavaPluginExtension>()
|
||||
java.sourceCompatibility = JavaVersion.VERSION_17
|
||||
java.targetCompatibility = JavaVersion.VERSION_17
|
||||
configurations.all {
|
||||
resolutionStrategy.eachDependency {
|
||||
if (requested.group == "org.jetbrains.kotlin") {
|
||||
// prevent transitive deps from bumping Koltin version
|
||||
useVersion(libs.versions.kotlin.get())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile>().configureEach {
|
||||
kotlinOptions {
|
||||
jvmTarget = "17"
|
||||
freeCompilerArgs = freeCompilerArgs + listOf("-Xjsr305=strict", "-Xjvm-default=all")
|
||||
plugins.withType(JavaPlugin::class).configureEach {
|
||||
tasks.withType<JavaCompile>().configureEach { options.release = 17 }
|
||||
}
|
||||
|
||||
tasks.withType<KotlinJvmCompile>().configureEach {
|
||||
compilerOptions {
|
||||
jvmTarget = JvmTarget.JVM_17
|
||||
freeCompilerArgs.addAll("-Xjsr305=strict", "-Xjvm-default=all")
|
||||
freeCompilerArgs.add("-Xjdk-release=17")
|
||||
}
|
||||
}
|
||||
|
||||
plugins.withType(IdeaPlugin::class).configureEach {
|
||||
val errorMessage = "Use IntelliJ Gradle import instead of running the `idea` task. See README for more information."
|
||||
val errorMessage =
|
||||
"Use IntelliJ Gradle import instead of running the `idea` task. See README for more information."
|
||||
|
||||
tasks.named("idea") {
|
||||
doFirst {
|
||||
throw GradleException(errorMessage)
|
||||
}
|
||||
}
|
||||
tasks.named("ideaModule") {
|
||||
doFirst {
|
||||
throw GradleException(errorMessage)
|
||||
}
|
||||
}
|
||||
tasks.named("idea") { doFirst { throw GradleException(errorMessage) } }
|
||||
tasks.named("ideaModule") { doFirst { throw GradleException(errorMessage) } }
|
||||
if (project == rootProject) {
|
||||
tasks.named("ideaProject") {
|
||||
doFirst {
|
||||
throw GradleException(errorMessage)
|
||||
}
|
||||
}
|
||||
tasks.named("ideaProject") { doFirst { throw GradleException(errorMessage) } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,11 +89,7 @@ plugins.withType(MavenPublishPlugin::class).configureEach {
|
||||
// dependency versions in generated POMs
|
||||
publications {
|
||||
withType(MavenPublication::class.java) {
|
||||
versionMapping {
|
||||
allVariants {
|
||||
fromResolutionResult()
|
||||
}
|
||||
}
|
||||
versionMapping { allVariants { fromResolutionResult() } }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,13 +97,10 @@ plugins.withType(MavenPublishPlugin::class).configureEach {
|
||||
|
||||
// settings.gradle.kts sets `--write-locks`
|
||||
// if Gradle command line contains this task name
|
||||
val updateDependencyLocks by tasks.registering {
|
||||
doLast {
|
||||
configurations
|
||||
.filter { it.isCanBeResolved }
|
||||
.forEach { it.resolve() }
|
||||
val updateDependencyLocks by
|
||||
tasks.registering {
|
||||
doLast { configurations.filter { it.isCanBeResolved }.forEach { it.resolve() } }
|
||||
}
|
||||
}
|
||||
|
||||
val allDependencies by tasks.registering(DependencyReportTask::class)
|
||||
|
||||
@@ -118,3 +128,41 @@ tasks.withType(JavaExec::class).configureEach {
|
||||
server = true
|
||||
}
|
||||
}
|
||||
|
||||
// Version Catalog library symbols.
|
||||
private val libs = the<LibrariesForLibs>()
|
||||
|
||||
private val licenseHeaderFile by lazy {
|
||||
rootProject.file("buildSrc/src/main/resources/license-header.star-block.txt")
|
||||
}
|
||||
|
||||
private fun KotlinGradleExtension.configureFormatter() {
|
||||
ktfmt(libs.versions.ktfmt.get()).googleStyle()
|
||||
licenseHeaderFile(licenseHeaderFile, "([a-zA-Z]|@file|//)")
|
||||
}
|
||||
|
||||
val originalRemoteName = System.getenv("PKL_ORIGINAL_REMOTE_NAME") ?: "origin"
|
||||
|
||||
spotless {
|
||||
ratchetFrom = "$originalRemoteName/main"
|
||||
|
||||
// When building root project, format buildSrc files too.
|
||||
// We need this because buildSrc is not a subproject of the root project, so a top-level
|
||||
// `spotlessApply` will not trigger `buildSrc:spotlessApply`.
|
||||
if (project === rootProject) {
|
||||
kotlinGradle {
|
||||
configureFormatter()
|
||||
target("*.kts", "buildSrc/*.kts", "buildSrc/src/*/kotlin/**/*.kts")
|
||||
}
|
||||
kotlin {
|
||||
ktfmt(libs.versions.ktfmt.get()).googleStyle()
|
||||
target("buildSrc/src/*/kotlin/**/*.kt")
|
||||
licenseHeaderFile(licenseHeaderFile)
|
||||
}
|
||||
} else {
|
||||
kotlinGradle {
|
||||
configureFormatter()
|
||||
target("*.kts")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.component.AdhocComponentWithVariants
|
||||
@@ -18,43 +33,58 @@ val fatJarConfiguration: Configuration = configurations.create("fatJar")
|
||||
val fatJarPublication: MavenPublication = publishing.publications.create<MavenPublication>("fatJar")
|
||||
|
||||
// ideally we'd configure this automatically based on project dependencies
|
||||
val firstPartySourcesJarsConfiguration: Configuration = configurations.create("firstPartySourcesJars")
|
||||
val firstPartySourcesJarsConfiguration: Configuration =
|
||||
configurations.create("firstPartySourcesJars")
|
||||
|
||||
val relocations = mapOf(
|
||||
// pkl-core dependencies
|
||||
"org.antlr.v4." to "org.pkl.thirdparty.antlr.v4.",
|
||||
"com.oracle.truffle" to "org.pkl.thirdparty.truffle",
|
||||
"org.graalvm." to "org.pkl.thirdparty.graalvm.",
|
||||
"org.organicdesign.fp." to "org.pkl.thirdparty.paguro.",
|
||||
"org.snakeyaml.engine." to "org.pkl.thirdparty.snakeyaml.engine.",
|
||||
"org.msgpack." to "org.pkl.thirdparty.msgpack.",
|
||||
"org.w3c.dom." to "org.pkl.thirdparty.w3c.dom",
|
||||
"com.oracle.svm.core." to "org.pkl.thirdparty.svm.",
|
||||
val relocations =
|
||||
mapOf(
|
||||
// pkl-core dependencies
|
||||
"org.organicdesign.fp." to "org.pkl.thirdparty.paguro.",
|
||||
"org.snakeyaml.engine." to "org.pkl.thirdparty.snakeyaml.engine.",
|
||||
"org.msgpack." to "org.pkl.thirdparty.msgpack.",
|
||||
"org.w3c.dom." to "org.pkl.thirdparty.w3c.dom.",
|
||||
"com.oracle.svm.core." to "org.pkl.thirdparty.svm.",
|
||||
|
||||
// pkl-cli dependencies
|
||||
"org.jline." to "org.pkl.thirdparty.jline.",
|
||||
"com.github.ajalt.clikt." to "org.pkl.thirdparty.clikt.",
|
||||
"kotlin." to "org.pkl.thirdparty.kotlin.",
|
||||
"kotlinx." to "org.pkl.thirdparty.kotlinx.",
|
||||
"org.intellij." to "org.pkl.thirdparty.intellij.",
|
||||
"org.fusesource.jansi." to "org.pkl.thirdparty.jansi",
|
||||
"org.fusesource.hawtjni." to "org.pkl.thirdparty.hawtjni",
|
||||
// pkl-cli dependencies
|
||||
"org.jline." to "org.pkl.thirdparty.jline.",
|
||||
"com.github.ajalt.clikt." to "org.pkl.thirdparty.clikt.",
|
||||
"com.github.ajalt.colormath." to "org.pkl.thirdparty.colormath.",
|
||||
"com.github.ajalt.mordant." to "org.pkl.thirdparty.mordant.",
|
||||
"com.sun.jna." to "org.pkl.thirdparty.jna.",
|
||||
"kotlin." to "org.pkl.thirdparty.kotlin.",
|
||||
"kotlinx." to "org.pkl.thirdparty.kotlinx.",
|
||||
"org.intellij." to "org.pkl.thirdparty.intellij.",
|
||||
"org.fusesource.jansi." to "org.pkl.thirdparty.jansi.",
|
||||
"org.fusesource.hawtjni." to "org.pkl.thirdparty.hawtjni.",
|
||||
|
||||
// pkl-doc dependencies
|
||||
"org.commonmark." to "org.pkl.thirdparty.commonmark.",
|
||||
"org.jetbrains." to "org.pkl.thirdparty.jetbrains.",
|
||||
|
||||
// pkl-config-java dependencies
|
||||
"io.leangen.geantyref." to "org.pkl.thirdparty.geantyref.",
|
||||
// pkl-doc dependencies
|
||||
"org.commonmark." to "org.pkl.thirdparty.commonmark.",
|
||||
"org.jetbrains." to "org.pkl.thirdparty.jetbrains.",
|
||||
|
||||
// pkl-codegen-java dependencies
|
||||
"com.squareup.javapoet." to "org.pkl.thirdparty.javapoet.",
|
||||
// pkl-config-java dependencies
|
||||
"io.leangen.geantyref." to "org.pkl.thirdparty.geantyref.",
|
||||
|
||||
// pkl-codegen-kotlin dependencies
|
||||
"com.squareup.kotlinpoet." to "org.pkl.thirdparty.kotlinpoet.",
|
||||
)
|
||||
// pkl-codegen-java dependencies
|
||||
"com.palantir.javapoet." to "org.pkl.thirdparty.javapoet.",
|
||||
|
||||
val nonRelocations = listOf("com/oracle/truffle/")
|
||||
// pkl-codegen-kotlin dependencies
|
||||
"com.squareup.kotlinpoet." to "org.pkl.thirdparty.kotlinpoet.",
|
||||
)
|
||||
|
||||
for ((key, value) in relocations) {
|
||||
if (!key.endsWith(".")) {
|
||||
throw GradleException(
|
||||
"Invalid relocation `\"$key\" to \"$value\"`: `$key` should end with a dot"
|
||||
)
|
||||
}
|
||||
if (!value.endsWith(".")) {
|
||||
throw GradleException(
|
||||
"Invalid relocation `\"$key\" to \"$value\"`: `$value` should end with a dot"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val nonRelocations = listOf("com/oracle/truffle/", "org/graalvm/")
|
||||
|
||||
tasks.shadowJar {
|
||||
inputs.property("relocations", relocations)
|
||||
@@ -63,12 +93,28 @@ tasks.shadowJar {
|
||||
|
||||
configurations = listOf(project.configurations.runtimeClasspath.get())
|
||||
|
||||
// not required at runtime / fat JARs can't be used in native-image builds anyway
|
||||
exclude("org/pkl/cli/svm/**")
|
||||
|
||||
exclude("META-INF/maven/**")
|
||||
exclude("META-INF/upgrade/**")
|
||||
exclude("META-INF/versions/19/**")
|
||||
|
||||
// org.antlr.v4.runtime.misc.RuleDependencyProcessor
|
||||
exclude("META-INF/services/javax.annotation.processing.Processor")
|
||||
val info = project.extensions.getByType<BuildInfo>()
|
||||
val minimumJvmTarget = JavaVersion.toVersion(info.jvmTarget)
|
||||
|
||||
manifest.attributes(
|
||||
// Certain exports need to be added to the Java modulepath for Java 17 to work properly with
|
||||
// shaded JARs. See the following link for an explanation of this syntax:
|
||||
// https://bugs.openjdk.org/browse/JDK-8335225
|
||||
"Add-Exports" to info.jpmsExportsForJarManifest
|
||||
)
|
||||
|
||||
// effectively, this results in calls excluding:
|
||||
// `META-INF/versions/{18-25}/**`
|
||||
// at the time of this writing; multi-release JARs beyond JDK 21 break the current
|
||||
// version of the Shadow plugin, and aren't needed for Truffle's use by Pkl.
|
||||
JavaVersionRange.startingAt(JavaLanguageVersion.of(minimumJvmTarget.majorVersion.toInt() + 1))
|
||||
.forEach { exclude("META-INF/versions/${it.asInt()}/**") }
|
||||
|
||||
exclude("module-info.*")
|
||||
|
||||
@@ -82,82 +128,81 @@ tasks.shadowJar {
|
||||
|
||||
// workaround for https://github.com/johnrengelman/shadow/issues/651
|
||||
components.withType(AdhocComponentWithVariants::class.java).forEach { c ->
|
||||
c.withVariantsFromConfiguration(project.configurations.shadowRuntimeElements.get()) {
|
||||
skip()
|
||||
c.withVariantsFromConfiguration(project.configurations.shadowRuntimeElements.get()) { skip() }
|
||||
}
|
||||
|
||||
val testFatJar by
|
||||
tasks.registering(Test::class) {
|
||||
testClassesDirs = files(tasks.test.get().testClassesDirs)
|
||||
classpath =
|
||||
// compiled test classes
|
||||
sourceSets.test.get().output +
|
||||
// fat Jar
|
||||
tasks.shadowJar.get().outputs.files +
|
||||
// test-only dependencies
|
||||
// (test dependencies that are also main dependencies must already be contained in fat Jar;
|
||||
// to verify that, we don't want to include them here)
|
||||
(configurations.testRuntimeClasspath.get() - configurations.runtimeClasspath.get())
|
||||
}
|
||||
}
|
||||
|
||||
val testFatJar by tasks.registering(Test::class) {
|
||||
testClassesDirs = files(tasks.test.get().testClassesDirs)
|
||||
classpath =
|
||||
// compiled test classes
|
||||
sourceSets.test.get().output +
|
||||
// fat Jar
|
||||
tasks.shadowJar.get().outputs.files +
|
||||
// test-only dependencies
|
||||
// (test dependencies that are also main dependencies must already be contained in fat Jar;
|
||||
// to verify that, we don't want to include them here)
|
||||
(configurations.testRuntimeClasspath.get() - configurations.runtimeClasspath.get())
|
||||
}
|
||||
tasks.check { dependsOn(testFatJar) }
|
||||
|
||||
tasks.check {
|
||||
dependsOn(testFatJar)
|
||||
}
|
||||
val validateFatJar by
|
||||
tasks.registering {
|
||||
val outputFile = layout.buildDirectory.file("validateFatJar/result.txt")
|
||||
inputs.files(tasks.shadowJar)
|
||||
inputs.property("nonRelocations", nonRelocations)
|
||||
outputs.file(outputFile)
|
||||
|
||||
val validateFatJar by tasks.registering {
|
||||
val outputFile = layout.buildDirectory.file("validateFatJar/result.txt")
|
||||
inputs.files(tasks.shadowJar)
|
||||
inputs.property("nonRelocations", nonRelocations)
|
||||
outputs.file(outputFile)
|
||||
|
||||
doLast {
|
||||
val unshadowedFiles = mutableListOf<String>()
|
||||
zipTree(tasks.shadowJar.get().outputs.files.singleFile).visit {
|
||||
val fileDetails = this
|
||||
val path = fileDetails.relativePath.pathString
|
||||
if (!(fileDetails.isDirectory ||
|
||||
path.startsWith("org/pkl/") ||
|
||||
path.startsWith("META-INF/") ||
|
||||
nonRelocations.any { path.startsWith(it) })) {
|
||||
// don't throw exception inside `visit`
|
||||
// as this gives a misleading "Could not expand ZIP" error message
|
||||
unshadowedFiles.add(path)
|
||||
doLast {
|
||||
val unshadowedFiles = mutableListOf<String>()
|
||||
zipTree(tasks.shadowJar.get().outputs.files.singleFile).visit {
|
||||
val fileDetails = this
|
||||
val path = fileDetails.relativePath.pathString
|
||||
if (
|
||||
!(fileDetails.isDirectory ||
|
||||
path.startsWith("org/pkl/") ||
|
||||
path.startsWith("META-INF/") ||
|
||||
nonRelocations.any { path.startsWith(it) })
|
||||
) {
|
||||
// don't throw exception inside `visit`
|
||||
// as this gives a misleading "Could not expand ZIP" error message
|
||||
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)
|
||||
}
|
||||
|
||||
val resolveSourcesJars by tasks.registering(ResolveSourcesJars::class) {
|
||||
configuration.set(configurations.runtimeClasspath)
|
||||
outputDir.set(layout.buildDirectory.dir("resolveSourcesJars"))
|
||||
}
|
||||
tasks.check { dependsOn(validateFatJar) }
|
||||
|
||||
val fatSourcesJar by tasks.registering(MergeSourcesJars::class) {
|
||||
plugins.withId("pklJavaLibrary") {
|
||||
inputJars.from(tasks.named("sourcesJar"))
|
||||
val resolveSourcesJars by
|
||||
tasks.registering(ResolveSourcesJars::class) {
|
||||
configuration.set(configurations.runtimeClasspath)
|
||||
outputDir.set(layout.buildDirectory.dir("resolveSourcesJars"))
|
||||
}
|
||||
inputJars.from(firstPartySourcesJarsConfiguration)
|
||||
inputJars.from(resolveSourcesJars.map { fileTree(it.outputDir) })
|
||||
|
||||
mergedBinaryJars.from(tasks.shadowJar)
|
||||
relocatedPackages.set(relocations)
|
||||
outputJar.fileProvider(provider {
|
||||
file(tasks.shadowJar.get().archiveFile.get().asFile.path.replace(".jar", "-sources.jar"))
|
||||
})
|
||||
}
|
||||
val fatSourcesJar by
|
||||
tasks.registering(MergeSourcesJars::class) {
|
||||
plugins.withId("pklJavaLibrary") { inputJars.from(tasks.named("sourcesJar")) }
|
||||
inputJars.from(firstPartySourcesJarsConfiguration)
|
||||
inputJars.from(resolveSourcesJars.map { fileTree(it.outputDir) })
|
||||
|
||||
artifacts {
|
||||
add("fatJar", tasks.shadowJar)
|
||||
}
|
||||
mergedBinaryJars.from(tasks.shadowJar)
|
||||
relocatedPackages.set(relocations)
|
||||
outputJar.fileProvider(
|
||||
provider {
|
||||
file(tasks.shadowJar.get().archiveFile.get().asFile.path.replace(".jar", "-sources.jar"))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
artifacts { add("fatJar", tasks.shadowJar) }
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
@@ -165,16 +210,12 @@ publishing {
|
||||
project.shadow.component(this)
|
||||
|
||||
// sources Jar is fat
|
||||
artifact(fatSourcesJar.flatMap { it.outputJar.asFile }) {
|
||||
classifier = "sources"
|
||||
}
|
||||
artifact(fatSourcesJar.flatMap { it.outputJar.asFile }) { classifier = "sources" }
|
||||
|
||||
plugins.withId("pklJavaLibrary") {
|
||||
val javadocJar by tasks.existing(Jar::class)
|
||||
// Javadoc Jar is not fat (didn't invest effort)
|
||||
artifact(javadocJar.flatMap { it.archiveFile }) {
|
||||
classifier = "javadoc"
|
||||
}
|
||||
artifact(javadocJar.flatMap { it.archiveFile }) { classifier = "javadoc" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,35 @@
|
||||
import java.nio.file.*
|
||||
import java.util.UUID
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import de.undercouch.gradle.tasks.download.Download
|
||||
import de.undercouch.gradle.tasks.download.Verify
|
||||
import kotlin.io.path.createDirectories
|
||||
|
||||
plugins {
|
||||
id("de.undercouch.download")
|
||||
}
|
||||
plugins { id("de.undercouch.download") }
|
||||
|
||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||
|
||||
val BuildInfo.GraalVm.downloadFile get(): File {
|
||||
val extension = if (buildInfo.os.isWindows) "zip" else "tar.gz"
|
||||
return file(homeDir).resolve("${baseName}.$extension")
|
||||
}
|
||||
|
||||
// tries to minimize chance of corruption by download-to-temp-file-and-move
|
||||
val downloadGraalVmAarch64 by tasks.registering(Download::class) {
|
||||
configureDownloadGraalVm(buildInfo.graalVmAarch64)
|
||||
}
|
||||
val downloadGraalVmAarch64 by
|
||||
tasks.registering(Download::class) { configureDownloadGraalVm(buildInfo.graalVmAarch64) }
|
||||
|
||||
val downloadGraalVmAmd64 by tasks.registering(Download::class) {
|
||||
configureDownloadGraalVm(buildInfo.graalVmAmd64)
|
||||
}
|
||||
val downloadGraalVmAmd64 by
|
||||
tasks.registering(Download::class) { configureDownloadGraalVm(buildInfo.graalVmAmd64) }
|
||||
|
||||
fun Download.configureDownloadGraalVm(graalvm: BuildInfo.GraalVm) {
|
||||
onlyIf {
|
||||
!graalvm.installDir.exists()
|
||||
}
|
||||
doLast {
|
||||
println("Downloaded GraalVm to ${graalvm.downloadFile}")
|
||||
}
|
||||
onlyIf { !graalvm.installDir.exists() }
|
||||
doLast { println("Downloaded GraalVm to ${graalvm.downloadFile}") }
|
||||
|
||||
src(graalvm.downloadUrl)
|
||||
dest(graalvm.downloadFile)
|
||||
@@ -38,77 +37,38 @@ fun Download.configureDownloadGraalVm(graalvm: BuildInfo.GraalVm) {
|
||||
tempAndMove(true)
|
||||
}
|
||||
|
||||
val verifyGraalVmAarch64 by tasks.registering(Verify::class) {
|
||||
configureVerifyGraalVm(buildInfo.graalVmAarch64)
|
||||
dependsOn(downloadGraalVmAarch64)
|
||||
}
|
||||
|
||||
val verifyGraalVmAmd64 by tasks.registering(Verify::class) {
|
||||
configureVerifyGraalVm(buildInfo.graalVmAmd64)
|
||||
dependsOn(downloadGraalVmAmd64)
|
||||
}
|
||||
|
||||
fun Verify.configureVerifyGraalVm(graalvm: BuildInfo.GraalVm) {
|
||||
onlyIf {
|
||||
!graalvm.installDir.exists()
|
||||
val verifyGraalVmAarch64 by
|
||||
tasks.registering(Verify::class) {
|
||||
configureVerifyGraalVm(buildInfo.graalVmAarch64)
|
||||
dependsOn(downloadGraalVmAarch64)
|
||||
}
|
||||
|
||||
val verifyGraalVmAmd64 by
|
||||
tasks.registering(Verify::class) {
|
||||
configureVerifyGraalVm(buildInfo.graalVmAmd64)
|
||||
dependsOn(downloadGraalVmAmd64)
|
||||
}
|
||||
|
||||
fun Verify.configureVerifyGraalVm(graalvm: BuildInfo.GraalVm) {
|
||||
onlyIf { !graalvm.installDir.exists() }
|
||||
|
||||
src(graalvm.downloadFile)
|
||||
checksum(buildInfo.libs.findVersion("graalVmSha256-${graalvm.osName}-${graalvm.arch}").get().toString())
|
||||
checksum(
|
||||
buildInfo.libs.findVersion("graalVmSha256-${graalvm.osName}-${graalvm.arch}").get().toString()
|
||||
)
|
||||
algorithm("SHA-256")
|
||||
}
|
||||
|
||||
// minimize chance of corruption by extract-to-random-dir-and-flip-symlink
|
||||
val installGraalVmAarch64 by tasks.registering {
|
||||
dependsOn(verifyGraalVmAarch64)
|
||||
configureInstallGraalVm(buildInfo.graalVmAarch64)
|
||||
}
|
||||
|
||||
// minimize chance of corruption by extract-to-random-dir-and-flip-symlink
|
||||
val installGraalVmAmd64 by tasks.registering {
|
||||
dependsOn(verifyGraalVmAmd64)
|
||||
configureInstallGraalVm(buildInfo.graalVmAmd64)
|
||||
}
|
||||
|
||||
fun Task.configureInstallGraalVm(graalVm: BuildInfo.GraalVm) {
|
||||
onlyIf {
|
||||
!graalVm.installDir.exists()
|
||||
@Suppress("unused")
|
||||
val installGraalVmAarch64 by
|
||||
tasks.registering(InstallGraalVm::class) {
|
||||
dependsOn(verifyGraalVmAarch64)
|
||||
graalVm = buildInfo.graalVmAarch64
|
||||
}
|
||||
|
||||
doLast {
|
||||
val distroDir = Paths.get(graalVm.homeDir, UUID.randomUUID().toString())
|
||||
|
||||
try {
|
||||
distroDir.createDirectories()
|
||||
println("Extracting ${graalVm.downloadFile} into $distroDir")
|
||||
// faster and more reliable than Gradle's `copy { from tarTree() }`
|
||||
exec {
|
||||
workingDir = file(distroDir)
|
||||
executable = "tar"
|
||||
args("--strip-components=1", "-xzf", graalVm.downloadFile)
|
||||
}
|
||||
|
||||
val distroBinDir = if (buildInfo.os.isMacOsX) distroDir.resolve("Contents/Home/bin") else distroDir.resolve("bin")
|
||||
|
||||
println("Installing native-image into $distroDir")
|
||||
exec {
|
||||
val executableName = if (buildInfo.os.isWindows) "gu.cmd" else "gu"
|
||||
executable = distroBinDir.resolve(executableName).toString()
|
||||
args("install", "--no-progress", "native-image")
|
||||
}
|
||||
|
||||
println("Creating symlink ${graalVm.installDir} for $distroDir")
|
||||
val tempLink = Paths.get(graalVm.homeDir, UUID.randomUUID().toString())
|
||||
Files.createSymbolicLink(tempLink, distroDir)
|
||||
try {
|
||||
Files.move(tempLink, graalVm.installDir.toPath(), StandardCopyOption.ATOMIC_MOVE)
|
||||
} catch (e: Exception) {
|
||||
try { delete(tempLink.toFile()) } catch (ignored: Exception) {}
|
||||
throw e
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
try { delete(distroDir) } catch (ignored: Exception) {}
|
||||
throw e
|
||||
}
|
||||
@Suppress("unused")
|
||||
val installGraalVmAmd64 by
|
||||
tasks.registering(InstallGraalVm::class) {
|
||||
dependsOn(verifyGraalVmAmd64)
|
||||
graalVm = buildInfo.graalVmAmd64
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/**
|
||||
* Allows to run Gradle plugin tests against different Gradle versions.
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Adds a `compatibilityTestX` task for every Gradle version X
|
||||
* between `ext.minSupportedGradleVersion` and `ext.maxSupportedGradleVersion`
|
||||
* that is not in `ext.gradleVersionsExcludedFromTesting`.
|
||||
* The list of available Gradle versions is obtained from services.gradle.org.
|
||||
* Adds lifecycle tasks to test against multiple Gradle versions at once, for example all Gradle release versions.
|
||||
* Compatibility test tasks run the same tests and use the same task configuration as the project's `test` task.
|
||||
* They set system properties for the Gradle version and distribution URL to be used.
|
||||
* These properties are consumed by the `AbstractTest` class.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
java
|
||||
}
|
||||
plugins { java }
|
||||
|
||||
val gradlePluginTests = extensions.create<GradlePluginTests>("gradlePluginTests")
|
||||
|
||||
@@ -24,18 +24,26 @@ tasks.addRule("Pattern: compatibilityTest[All|Releases|Latest|Candidate|Nightly|
|
||||
when (val taskNameSuffix = matchResult.groupValues[1]) {
|
||||
"All" ->
|
||||
task("compatibilityTestAll") {
|
||||
dependsOn("compatibilityTestReleases", "compatibilityTestCandidate", "compatibilityTestNightly")
|
||||
dependsOn(
|
||||
"compatibilityTestReleases",
|
||||
"compatibilityTestCandidate",
|
||||
"compatibilityTestNightly",
|
||||
)
|
||||
}
|
||||
// releases in configured range
|
||||
"Releases" ->
|
||||
task("compatibilityTestReleases") {
|
||||
val versionInfos = GradleVersionInfo.fetchReleases()
|
||||
val versionsToTestAgainst = versionInfos.filter { versionInfo ->
|
||||
val v = versionInfo.gradleVersion
|
||||
!versionInfo.broken &&
|
||||
v in gradlePluginTests.minGradleVersion..gradlePluginTests.maxGradleVersion &&
|
||||
v !in gradlePluginTests.skippedGradleVersions
|
||||
}
|
||||
val allVersions =
|
||||
versionInfos
|
||||
.filter { versionInfo ->
|
||||
val v = versionInfo.gradleVersion
|
||||
!versionInfo.broken &&
|
||||
v in gradlePluginTests.minGradleVersion..gradlePluginTests.maxGradleVersion &&
|
||||
v !in gradlePluginTests.skippedGradleVersions
|
||||
}
|
||||
.sortedBy { it.gradleVersion }
|
||||
val versionsToTestAgainst = listOf(allVersions.first(), allVersions.last())
|
||||
|
||||
dependsOn(versionsToTestAgainst.map { createCompatibilityTestTask(it) })
|
||||
}
|
||||
@@ -45,8 +53,10 @@ tasks.addRule("Pattern: compatibilityTest[All|Releases|Latest|Candidate|Nightly|
|
||||
val versionInfo = GradleVersionInfo.fetchCurrent()
|
||||
if (versionInfo.version == gradle.gradleVersion) {
|
||||
doLast {
|
||||
println("No new Gradle release available. " +
|
||||
"(Run `gradlew test` to test against ${versionInfo.version}.)")
|
||||
println(
|
||||
"No new Gradle release available. " +
|
||||
"(Run `gradlew test` to test against ${versionInfo.version}.)"
|
||||
)
|
||||
}
|
||||
} else {
|
||||
dependsOn(createCompatibilityTestTask(versionInfo))
|
||||
@@ -59,9 +69,7 @@ tasks.addRule("Pattern: compatibilityTest[All|Releases|Latest|Candidate|Nightly|
|
||||
if (versionInfo?.activeRc == true) {
|
||||
dependsOn(createCompatibilityTestTask(versionInfo))
|
||||
} else {
|
||||
doLast {
|
||||
println("No active Gradle release candidate available.")
|
||||
}
|
||||
doLast { println("No active Gradle release candidate available.") }
|
||||
}
|
||||
}
|
||||
// latest nightly
|
||||
@@ -73,17 +81,17 @@ tasks.addRule("Pattern: compatibilityTest[All|Releases|Latest|Candidate|Nightly|
|
||||
// explicit version
|
||||
else ->
|
||||
createCompatibilityTestTask(
|
||||
taskNameSuffix,
|
||||
"https://services.gradle.org/distributions-snapshots/gradle-$taskNameSuffix-bin.zip"
|
||||
taskNameSuffix,
|
||||
"https://services.gradle.org/distributions-snapshots/gradle-$taskNameSuffix-bin.zip",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun createCompatibilityTestTask(versionInfo: GradleVersionInfo): Task =
|
||||
createCompatibilityTestTask(versionInfo.version, versionInfo.downloadUrl)
|
||||
fun createCompatibilityTestTask(versionInfo: GradleVersionInfo): TaskProvider<Test> =
|
||||
createCompatibilityTestTask(versionInfo.version, versionInfo.downloadUrl)
|
||||
|
||||
fun createCompatibilityTestTask(version: String, downloadUrl: String): Task {
|
||||
return tasks.create("compatibilityTest$version", Test::class.java) {
|
||||
fun createCompatibilityTestTask(version: String, downloadUrl: String): TaskProvider<Test> {
|
||||
return tasks.register("compatibilityTest$version", Test::class.java) {
|
||||
mustRunAfter(tasks.test)
|
||||
|
||||
maxHeapSize = tasks.test.get().maxHeapSize
|
||||
|
||||
@@ -1,20 +1,33 @@
|
||||
plugins {
|
||||
base
|
||||
}
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
plugins { base }
|
||||
|
||||
val htmlValidator = extensions.create<HtmlValidator>("htmlValidator", project)
|
||||
|
||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||
|
||||
val validatorConfiguration: Configuration = configurations.create("validator") {
|
||||
resolutionStrategy.eachDependency {
|
||||
if (requested.group == "log4j" && requested.name == "log4j") {
|
||||
@Suppress("UnstableApiUsage")
|
||||
useTarget(buildInfo.libs.findLibrary("log4j12Api").get())
|
||||
because("mitigate critical security vulnerabilities")
|
||||
val validatorConfiguration: Configuration =
|
||||
configurations.create("validator") {
|
||||
resolutionStrategy.eachDependency {
|
||||
if (requested.group == "log4j" && requested.name == "log4j") {
|
||||
@Suppress("UnstableApiUsage") useTarget(buildInfo.libs.findLibrary("log4j12Api").get())
|
||||
because("mitigate critical security vulnerabilities")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@Suppress("UnstableApiUsage")
|
||||
@@ -32,27 +45,29 @@ dependencies {
|
||||
}
|
||||
}
|
||||
|
||||
val validateHtml by tasks.registering(JavaExec::class) {
|
||||
val resultFile = layout.buildDirectory.file("validateHtml/result.txt")
|
||||
inputs.files(htmlValidator.sources)
|
||||
outputs.file(resultFile)
|
||||
val validateHtml by
|
||||
tasks.registering(JavaExec::class) {
|
||||
val resultFile = layout.buildDirectory.file("validateHtml/result.txt")
|
||||
inputs.files(htmlValidator.sources)
|
||||
outputs.file(resultFile)
|
||||
|
||||
classpath = validatorConfiguration
|
||||
mainClass.set("nu.validator.client.SimpleCommandLineValidator")
|
||||
args("--skip-non-html") // --also-check-css doesn't work (still checks css as html), so limit to html files
|
||||
args("--filterpattern", "(.*)Consider adding “lang=(.*)")
|
||||
args("--filterpattern", "(.*)Consider adding a “lang” attribute(.*)")
|
||||
args("--filterpattern", "(.*)unrecognized media “amzn-kf8”(.*)") // kindle
|
||||
// for debugging
|
||||
// args "--verbose"
|
||||
args(htmlValidator.sources)
|
||||
classpath = validatorConfiguration
|
||||
mainClass.set("nu.validator.client.SimpleCommandLineValidator")
|
||||
args(
|
||||
"--skip-non-html"
|
||||
) // --also-check-css doesn't work (still checks css as html), so limit to html files
|
||||
args("--filterpattern", "(.*)Consider adding “lang=(.*)")
|
||||
args("--filterpattern", "(.*)Consider adding a “lang” attribute(.*)")
|
||||
args("--filterpattern", "(.*)unrecognized media “amzn-kf8”(.*)") // kindle
|
||||
// for debugging
|
||||
// args "--verbose"
|
||||
args(htmlValidator.sources)
|
||||
|
||||
// write a basic result file s.t. gradle can consider task up-to-date
|
||||
// writing a result file in case validation fails is not easily possible with JavaExec, but also not strictly necessary
|
||||
doFirst { project.delete(resultFile) }
|
||||
doLast { resultFile.get().asFile.writeText("Success.") }
|
||||
}
|
||||
// write a basic result file s.t. gradle can consider task up-to-date
|
||||
// writing a result file in case validation fails is not easily possible with JavaExec, but also
|
||||
// not strictly necessary
|
||||
doFirst { project.delete(resultFile) }
|
||||
doLast { resultFile.get().asFile.writeText("Success.") }
|
||||
}
|
||||
|
||||
tasks.check {
|
||||
dependsOn(validateHtml)
|
||||
}
|
||||
tasks.check { dependsOn(validateHtml) }
|
||||
|
||||
131
buildSrc/src/main/kotlin/pklJavaExecutable.gradle.kts
Normal file
131
buildSrc/src/main/kotlin/pklJavaExecutable.gradle.kts
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import kotlin.io.path.createDirectories
|
||||
import kotlin.io.path.writeText
|
||||
import org.gradle.kotlin.dsl.support.serviceOf
|
||||
|
||||
plugins {
|
||||
id("pklJavaLibrary")
|
||||
// id("pklPublishLibrary")
|
||||
id("com.github.johnrengelman.shadow")
|
||||
}
|
||||
|
||||
val executableSpec = project.extensions.create("executable", ExecutableSpec::class.java)
|
||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||
|
||||
val javaExecutable by
|
||||
tasks.registering(ExecutableJar::class) {
|
||||
group = "build"
|
||||
dependsOn(tasks.jar)
|
||||
inJar = tasks.shadowJar.flatMap { it.archiveFile }
|
||||
val effectiveJavaName =
|
||||
executableSpec.javaName.map { name -> if (buildInfo.os.isWindows) "$name.bat" else name }
|
||||
outJar = layout.buildDirectory.dir("executable").flatMap { it.file(effectiveJavaName) }
|
||||
|
||||
// uncomment for debugging
|
||||
// jvmArgs.addAll("-ea", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005")
|
||||
}
|
||||
|
||||
fun Task.setupTestStartJavaExecutable(launcher: Provider<JavaLauncher>? = null) {
|
||||
group = "verification"
|
||||
dependsOn(javaExecutable)
|
||||
|
||||
// dummy output to satisfy up-to-date check
|
||||
val outputFile = layout.buildDirectory.file("testStartJavaExecutable/$name")
|
||||
outputs.file(outputFile)
|
||||
|
||||
val execOutput =
|
||||
providers.exec {
|
||||
val executablePath = javaExecutable.get().outputs.files.singleFile
|
||||
if (launcher?.isPresent == true) {
|
||||
commandLine(
|
||||
launcher.get().executablePath.asFile.absolutePath,
|
||||
"-jar",
|
||||
executablePath.absolutePath,
|
||||
"--version",
|
||||
)
|
||||
} else {
|
||||
commandLine(executablePath.absolutePath, "--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 {
|
||||
parent.createDirectories()
|
||||
} catch (ignored: java.nio.file.FileAlreadyExistsException) {}
|
||||
writeText("OK")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val testStartJavaExecutable by tasks.registering { setupTestStartJavaExecutable() }
|
||||
|
||||
// Setup `testStartJavaExecutable` tasks for multi-JDK testing.
|
||||
val testStartJavaExecutableOnOtherJdks =
|
||||
buildInfo.jdkTestRange.map { jdkTarget ->
|
||||
tasks.register("testStartJavaExecutableJdk${jdkTarget.asInt()}") {
|
||||
enabled = buildInfo.isVersionEnabled(jdkTarget)
|
||||
val toolChainService: JavaToolchainService = serviceOf()
|
||||
val launcher = toolChainService.launcherFor { languageVersion = jdkTarget }
|
||||
setupTestStartJavaExecutable(launcher)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.assemble { dependsOn(javaExecutable) }
|
||||
|
||||
tasks.check {
|
||||
dependsOn(testStartJavaExecutable)
|
||||
dependsOn(testStartJavaExecutableOnOtherJdks)
|
||||
}
|
||||
|
||||
// publishing {
|
||||
// publications {
|
||||
// // need to put in `afterEvaluate` because `artifactId` cannot be set lazily.
|
||||
// project.afterEvaluate {
|
||||
// register<MavenPublication>("javaExecutable") {
|
||||
// artifactId = executableSpec.javaPublicationName.get()
|
||||
//
|
||||
// artifact(javaExecutable.map { it.outputs.files.singleFile }) {
|
||||
// classifier = null
|
||||
// extension = "bin"
|
||||
// builtBy(javaExecutable)
|
||||
// }
|
||||
//
|
||||
// pom {
|
||||
// url = executableSpec.website
|
||||
// description =
|
||||
// executableSpec.documentationName.map { name ->
|
||||
// """
|
||||
// $name executable for Java.
|
||||
// Can be executed directly, or with `java -jar <path/to/jpkl>`.
|
||||
// Requires Java 17 or higher.
|
||||
// """
|
||||
// .trimIndent()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// signing { project.afterEvaluate { sign(publishing.publications["javaExecutable"]) } }
|
||||
@@ -1,22 +1,47 @@
|
||||
@file:Suppress("HttpUrlsUsage")
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@file:Suppress("HttpUrlsUsage", "unused")
|
||||
|
||||
import org.gradle.accessors.dm.LibrariesForLibs
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
`jvm-toolchains`
|
||||
`jvm-test-suite`
|
||||
id("pklKotlinTest")
|
||||
id("com.diffplug.spotless")
|
||||
}
|
||||
|
||||
// make sources Jar available to other subprojects
|
||||
val sourcesJarConfiguration = configurations.register("sourcesJar")
|
||||
val sourcesJarConfiguration: Provider<Configuration> = configurations.register("sourcesJar")
|
||||
|
||||
// Version Catalog library symbols.
|
||||
val libs = the<LibrariesForLibs>()
|
||||
|
||||
// Build configuration.
|
||||
val info = project.extensions.getByType<BuildInfo>()
|
||||
|
||||
java {
|
||||
withSourcesJar() // creates `sourcesJar` task
|
||||
withJavadocJar()
|
||||
|
||||
toolchain {
|
||||
languageVersion = info.jdkToolchainVersion
|
||||
vendor = info.jdkVendor
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
@@ -27,18 +52,25 @@ artifacts {
|
||||
spotless {
|
||||
java {
|
||||
googleJavaFormat(libs.versions.googleJavaFormat.get())
|
||||
targetExclude("**/generated/**", "**/build/**")
|
||||
target("src/*/java/**/*.java")
|
||||
licenseHeaderFile(rootProject.file("buildSrc/src/main/resources/license-header.star-block.txt"))
|
||||
}
|
||||
kotlin {
|
||||
ktfmt(libs.versions.ktfmt.get()).googleStyle()
|
||||
target("src/*/kotlin/**/*.kt")
|
||||
licenseHeaderFile(rootProject.file("buildSrc/src/main/resources/license-header.star-block.txt"))
|
||||
}
|
||||
}
|
||||
|
||||
tasks.compileKotlin {
|
||||
enabled = false
|
||||
}
|
||||
tasks.compileKotlin { enabled = false }
|
||||
|
||||
tasks.jar {
|
||||
manifest {
|
||||
attributes += mapOf("Automatic-Module-Name" to "org.${project.name.replace("-", ".")}")
|
||||
attributes +=
|
||||
mapOf(
|
||||
"Automatic-Module-Name" to "org.${project.name.replace("-", ".")}",
|
||||
"Add-Exports" to info.jpmsExportsForJarManifest,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,19 +81,59 @@ tasks.javadoc {
|
||||
(options as StandardJavadocDocletOptions).addStringOption("Xdoclint:none", "-quiet")
|
||||
}
|
||||
|
||||
val workAroundKotlinGradlePluginBug by tasks.registering {
|
||||
doLast {
|
||||
// Works around this problem, which sporadically appears and disappears in different subprojects:
|
||||
// A problem was found with the configuration of task ':pkl-executor:compileJava' (type 'JavaCompile').
|
||||
// > Directory '[...]/pkl/pkl-executor/build/classes/kotlin/main'
|
||||
// specified for property 'compileKotlinOutputClasses' does not exist.
|
||||
layout.buildDirectory.dir("classes/kotlin/main").get().asFile.mkdirs()
|
||||
val workAroundKotlinGradlePluginBug by
|
||||
tasks.registering {
|
||||
doLast {
|
||||
// Works around this problem, which sporadically appears and disappears in different
|
||||
// subprojects:
|
||||
// A problem was found with the configuration of task ':pkl-executor:compileJava' (type
|
||||
// 'JavaCompile').
|
||||
// > Directory '[...]/pkl/pkl-executor/build/classes/kotlin/main'
|
||||
// specified for property 'compileKotlinOutputClasses' does not exist.
|
||||
layout.buildDirectory.dir("classes/kotlin/main").get().asFile.mkdirs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val truffleJavacArgs =
|
||||
listOf(
|
||||
// TODO: determine correct limits for Truffle specializations
|
||||
// (see https://graalvm.slack.com/archives/CNQSB2DHD/p1712380902746829)
|
||||
"-Atruffle.dsl.SuppressWarnings=truffle-limit"
|
||||
)
|
||||
|
||||
tasks.compileJava {
|
||||
javaCompiler = info.javaCompiler
|
||||
dependsOn(workAroundKotlinGradlePluginBug)
|
||||
// TODO: determine correct limits for Truffle specializations
|
||||
// (see https://graalvm.slack.com/archives/CNQSB2DHD/p1712380902746829)
|
||||
options.compilerArgs.add("-Atruffle.dsl.SuppressWarnings=truffle-limit")
|
||||
options.compilerArgs.addAll(truffleJavacArgs + info.jpmsAddModulesFlags)
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile>().configureEach {
|
||||
javaCompiler = info.javaCompiler
|
||||
options.release = info.jvmTarget
|
||||
}
|
||||
|
||||
tasks.withType<JavaExec>().configureEach { jvmArgs(info.jpmsAddModulesFlags) }
|
||||
|
||||
fun Test.configureJdkTestTask(launcher: Provider<JavaLauncher>) {
|
||||
useJUnitPlatform()
|
||||
javaLauncher = launcher
|
||||
systemProperties.putAll(info.testProperties)
|
||||
jvmArgs.addAll(info.jpmsAddModulesFlags)
|
||||
}
|
||||
|
||||
tasks.test { configureJdkTestTask(info.javaTestLauncher) }
|
||||
|
||||
// Prepare test tasks for each JDK version which is within the test target suite for Pkl. Each task
|
||||
// uses a pinned JDK toolchain version, and is named for the major version which is tested.
|
||||
//
|
||||
// Test tasks configured in this manner are executed manually by name, e.g. `./gradlew testJdk11`,
|
||||
// and automatically as dependencies of `check`.
|
||||
//
|
||||
// We omit the current JDK from this list because it is already tested, in effect, by the default
|
||||
// `test` task.
|
||||
//
|
||||
// Pkl subprojects may elect to further configure these tasks as needed; by default, each task
|
||||
// inherits the configuration of the default `test` task (aside from an overridden launcher).
|
||||
val jdkTestTasks = info.multiJdkTestingWith(tasks.test) { (_, jdk) -> configureJdkTestTask(jdk) }
|
||||
|
||||
tasks.check { dependsOn(jdkTestTasks) }
|
||||
|
||||
@@ -1,11 +1,28 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import org.gradle.accessors.dm.LibrariesForLibs
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
|
||||
|
||||
plugins {
|
||||
id("pklJavaLibrary")
|
||||
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
// Build configuration.
|
||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||
|
||||
// Version Catalog library symbols.
|
||||
@@ -24,10 +41,9 @@ tasks.compileKotlin {
|
||||
enabled = true // disabled by pklJavaLibrary
|
||||
}
|
||||
|
||||
spotless {
|
||||
kotlin {
|
||||
ktfmt(libs.versions.ktfmt.get()).googleStyle()
|
||||
targetExclude("**/generated/**", "**/build/**")
|
||||
licenseHeaderFile(rootProject.file("buildSrc/src/main/resources/license-header.star-block.txt"))
|
||||
tasks.withType<KotlinJvmCompile>().configureEach {
|
||||
compilerOptions {
|
||||
jvmTarget = JvmTarget.fromTarget(buildInfo.jvmTarget.toString())
|
||||
freeCompilerArgs.addAll("-Xjdk-release=${buildInfo.jvmTarget}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,39 @@
|
||||
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import java.net.URI
|
||||
import org.gradle.accessors.dm.LibrariesForLibs
|
||||
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
|
||||
|
||||
plugins {
|
||||
`jvm-test-suite`
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||
|
||||
dependencies {
|
||||
testImplementation(buildInfo.libs.findLibrary("assertj").get())
|
||||
testImplementation(buildInfo.libs.findLibrary("junitApi").get())
|
||||
testImplementation(buildInfo.libs.findLibrary("junitParams").get())
|
||||
testImplementation(buildInfo.libs.findLibrary("kotlinStdLib").get())
|
||||
val libs = the<LibrariesForLibs>()
|
||||
|
||||
testRuntimeOnly(buildInfo.libs.findLibrary("junitEngine").get())
|
||||
dependencies {
|
||||
testImplementation(libs.assertj)
|
||||
testImplementation(libs.junitApi)
|
||||
testImplementation(libs.junitParams)
|
||||
testImplementation(libs.kotlinStdLib)
|
||||
|
||||
testRuntimeOnly(libs.junitEngine)
|
||||
testRuntimeOnly(libs.junitLauncher)
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
@@ -24,34 +44,36 @@ tasks.withType<Test>().configureEach {
|
||||
// enable checking of stdlib return types
|
||||
systemProperty("org.pkl.testMode", "true")
|
||||
|
||||
reports.named("html") {
|
||||
enabled = true
|
||||
}
|
||||
reports.named("html") { enabled = true }
|
||||
|
||||
testLogging {
|
||||
exceptionFormat = TestExceptionFormat.FULL
|
||||
}
|
||||
testLogging { exceptionFormat = TestExceptionFormat.FULL }
|
||||
|
||||
addTestListener(object : TestListener {
|
||||
override fun beforeSuite(suite: TestDescriptor) {}
|
||||
override fun beforeTest(testDescriptor: TestDescriptor) {}
|
||||
override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {}
|
||||
addTestListener(
|
||||
object : TestListener {
|
||||
override fun beforeSuite(suite: TestDescriptor) {}
|
||||
|
||||
// print report link at end of task, not just at end of build
|
||||
override fun afterSuite(descriptor: TestDescriptor, result: TestResult) {
|
||||
if (descriptor.parent != null) return // only interested in overall result
|
||||
override fun beforeTest(testDescriptor: TestDescriptor) {}
|
||||
|
||||
if (result.resultType == TestResult.ResultType.FAILURE) {
|
||||
println("\nThere were failing tests. See the report at: ${fixFileUri(testTask.reports.html.entryPoint.toURI())}")
|
||||
override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {}
|
||||
|
||||
// print report link at end of task, not just at end of build
|
||||
override fun afterSuite(descriptor: TestDescriptor, result: TestResult) {
|
||||
if (descriptor.parent != null) return // only interested in overall result
|
||||
|
||||
if (result.resultType == TestResult.ResultType.FAILURE) {
|
||||
println(
|
||||
"\nThere were failing tests. See the report at: ${fixFileUri(testTask.reports.html.entryPoint.toURI())}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// makes links clickable on macOS
|
||||
private fun fixFileUri(uri: URI): URI {
|
||||
if ("file" == uri.scheme && !uri.schemeSpecificPart.startsWith("//")) {
|
||||
return URI.create("file://" + uri.schemeSpecificPart)
|
||||
}
|
||||
return uri
|
||||
}
|
||||
}
|
||||
|
||||
// makes links clickable on macOS
|
||||
private fun fixFileUri(uri: URI): URI {
|
||||
if ("file" == uri.scheme && !uri.schemeSpecificPart.startsWith("//")) {
|
||||
return URI.create("file://" + uri.schemeSpecificPart)
|
||||
}
|
||||
return uri
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
val assembleNative by tasks.registering {}
|
||||
|
||||
val testNative by tasks.registering {}
|
||||
|
||||
val checkNative by tasks.registering {
|
||||
dependsOn(testNative)
|
||||
}
|
||||
|
||||
val buildNative by tasks.registering {
|
||||
dependsOn(assembleNative, checkNative)
|
||||
}
|
||||
291
buildSrc/src/main/kotlin/pklNativeExecutable.gradle.kts
Normal file
291
buildSrc/src/main/kotlin/pklNativeExecutable.gradle.kts
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import kotlin.io.path.createDirectories
|
||||
import kotlin.io.path.writeText
|
||||
|
||||
plugins {
|
||||
id("pklGraalVm")
|
||||
id("pklJavaLibrary")
|
||||
id("pklNativeLifecycle")
|
||||
id("pklPublishLibrary")
|
||||
id("com.github.johnrengelman.shadow")
|
||||
}
|
||||
|
||||
// assumes that `pklJavaExecutable` is also applied
|
||||
val executableSpec = project.extensions.getByType<ExecutableSpec>()
|
||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||
|
||||
val stagedMacAmd64Executable: Configuration by configurations.creating
|
||||
val stagedMacAarch64Executable: Configuration by configurations.creating
|
||||
val stagedLinuxAmd64Executable: Configuration by configurations.creating
|
||||
val stagedLinuxAarch64Executable: Configuration by configurations.creating
|
||||
val stagedAlpineLinuxAmd64Executable: Configuration by configurations.creating
|
||||
val stagedWindowsAmd64Executable: Configuration by configurations.creating
|
||||
|
||||
dependencies {
|
||||
fun executableFile(suffix: String) =
|
||||
files(
|
||||
layout.buildDirectory.dir("executable").map { dir ->
|
||||
dir.file(executableSpec.name.map { "$it-$suffix" })
|
||||
}
|
||||
)
|
||||
stagedMacAarch64Executable(executableFile("macos-aarch64"))
|
||||
stagedMacAmd64Executable(executableFile("macos-amd64"))
|
||||
stagedLinuxAmd64Executable(executableFile("linux-amd64"))
|
||||
stagedLinuxAarch64Executable(executableFile("linux-aarch64"))
|
||||
stagedAlpineLinuxAmd64Executable(executableFile("alpine-linux-amd64"))
|
||||
stagedWindowsAmd64Executable(executableFile("windows-amd64.exe"))
|
||||
}
|
||||
|
||||
private fun NativeImageBuild.amd64() {
|
||||
arch = Architecture.AMD64
|
||||
dependsOn(":installGraalVmAmd64")
|
||||
}
|
||||
|
||||
private fun NativeImageBuild.aarch64() {
|
||||
arch = Architecture.AARCH64
|
||||
dependsOn(":installGraalVmAarch64")
|
||||
}
|
||||
|
||||
private fun NativeImageBuild.setClasspath() {
|
||||
classpath.from(sourceSets.main.map { it.output })
|
||||
classpath.from(
|
||||
project(":pkl-commons-cli").extensions.getByType(SourceSetContainer::class)["svm"].output
|
||||
)
|
||||
classpath.from(configurations.runtimeClasspath)
|
||||
}
|
||||
|
||||
val macExecutableAmd64 by
|
||||
tasks.registering(NativeImageBuild::class) {
|
||||
imageName = executableSpec.name.map { "$it-macos-amd64" }
|
||||
mainClass = executableSpec.mainClass
|
||||
amd64()
|
||||
setClasspath()
|
||||
}
|
||||
|
||||
val macExecutableAarch64 by
|
||||
tasks.registering(NativeImageBuild::class) {
|
||||
imageName = executableSpec.name.map { "$it-macos-aarch64" }
|
||||
mainClass = executableSpec.mainClass
|
||||
aarch64()
|
||||
setClasspath()
|
||||
}
|
||||
|
||||
val linuxExecutableAmd64 by
|
||||
tasks.registering(NativeImageBuild::class) {
|
||||
imageName = executableSpec.name.map { "$it-linux-amd64" }
|
||||
mainClass = executableSpec.mainClass
|
||||
amd64()
|
||||
setClasspath()
|
||||
}
|
||||
|
||||
val linuxExecutableAarch64 by
|
||||
tasks.registering(NativeImageBuild::class) {
|
||||
imageName = executableSpec.name.map { "$it-linux-aarch64" }
|
||||
mainClass = executableSpec.mainClass
|
||||
aarch64()
|
||||
setClasspath()
|
||||
// Ensure compatibility for kernels with page size set to 4k, 16k and 64k
|
||||
// (e.g. Raspberry Pi 5, Asahi Linux)
|
||||
extraNativeImageArgs.add("-H:PageSize=65536")
|
||||
}
|
||||
|
||||
val alpineExecutableAmd64 by
|
||||
tasks.registering(NativeImageBuild::class) {
|
||||
imageName = executableSpec.name.map { "$it-alpine-linux-amd64" }
|
||||
mainClass = executableSpec.mainClass
|
||||
amd64()
|
||||
setClasspath()
|
||||
extraNativeImageArgs.addAll(listOf("--static", "--libc=musl"))
|
||||
}
|
||||
|
||||
val windowsExecutableAmd64 by
|
||||
tasks.registering(NativeImageBuild::class) {
|
||||
imageName = executableSpec.name.map { "$it-windows-amd64" }
|
||||
mainClass = executableSpec.mainClass
|
||||
amd64()
|
||||
setClasspath()
|
||||
extraNativeImageArgs.add("-Dfile.encoding=UTF-8")
|
||||
}
|
||||
|
||||
val assembleNative by tasks.existing
|
||||
|
||||
val testStartNativeExecutable by
|
||||
tasks.registering {
|
||||
dependsOn(assembleNative)
|
||||
|
||||
// dummy file for up-to-date checking
|
||||
val outputFile = project.layout.buildDirectory.file("testStartNativeExecutable/output.txt")
|
||||
outputs.file(outputFile)
|
||||
|
||||
val execOutput =
|
||||
providers.exec { 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 {
|
||||
parent.createDirectories()
|
||||
} catch (ignored: java.nio.file.FileAlreadyExistsException) {}
|
||||
writeText("OK")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expose underlying task's outputs
|
||||
private fun <T : Task> Task.wraps(other: TaskProvider<T>) {
|
||||
dependsOn(other)
|
||||
outputs.files(other)
|
||||
}
|
||||
|
||||
val testNative by tasks.existing { dependsOn(testStartNativeExecutable) }
|
||||
|
||||
val assembleNativeMacOsAarch64 by tasks.existing { wraps(macExecutableAarch64) }
|
||||
|
||||
val assembleNativeMacOsAmd64 by tasks.existing { wraps(macExecutableAmd64) }
|
||||
|
||||
val assembleNativeLinuxAarch64 by tasks.existing { wraps(linuxExecutableAarch64) }
|
||||
|
||||
val assembleNativeLinuxAmd64 by tasks.existing { wraps(linuxExecutableAmd64) }
|
||||
|
||||
val assembleNativeAlpineLinuxAmd64 by tasks.existing { wraps(alpineExecutableAmd64) }
|
||||
|
||||
val assembleNativeWindowsAmd64 by tasks.existing { wraps(windowsExecutableAmd64) }
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
// need to put in `afterEvaluate` because `artifactId` cannot be set lazily.
|
||||
project.afterEvaluate {
|
||||
create<MavenPublication>("macExecutableAmd64") {
|
||||
artifactId = "${executableSpec.publicationName.get()}-macos-amd64"
|
||||
artifact(stagedMacAmd64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedMacAmd64Executable)
|
||||
}
|
||||
pom {
|
||||
name = "${executableSpec.publicationName.get()}-macos-amd64"
|
||||
url = executableSpec.website
|
||||
description =
|
||||
executableSpec.documentationName.map { name ->
|
||||
"Native $name executable for macOS/amd64."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
create<MavenPublication>("macExecutableAarch64") {
|
||||
artifactId = "${executableSpec.publicationName.get()}-macos-aarch64"
|
||||
artifact(stagedMacAarch64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedMacAarch64Executable)
|
||||
}
|
||||
pom {
|
||||
name = "${executableSpec.publicationName.get()}-macos-aarch64"
|
||||
url = executableSpec.website
|
||||
description =
|
||||
executableSpec.documentationName.map { name ->
|
||||
"Native $name executable for macOS/aarch64."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
create<MavenPublication>("linuxExecutableAmd64") {
|
||||
artifactId = "${executableSpec.publicationName.get()}-linux-amd64"
|
||||
artifact(stagedLinuxAmd64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedLinuxAmd64Executable)
|
||||
}
|
||||
pom {
|
||||
name = "${executableSpec.publicationName.get()}-linux-amd64"
|
||||
url = executableSpec.website
|
||||
description =
|
||||
executableSpec.documentationName.map { name ->
|
||||
"Native $name executable for linux/amd64."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
create<MavenPublication>("linuxExecutableAarch64") {
|
||||
artifactId = "${executableSpec.publicationName.get()}-linux-aarch64"
|
||||
artifact(stagedLinuxAarch64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedLinuxAarch64Executable)
|
||||
}
|
||||
pom {
|
||||
name = "${executableSpec.publicationName.get()}-linux-aarch64"
|
||||
url = executableSpec.website
|
||||
description =
|
||||
executableSpec.documentationName.map { name ->
|
||||
"Native $name executable for linux/aarch64."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
create<MavenPublication>("alpineLinuxExecutableAmd64") {
|
||||
artifactId = "${executableSpec.publicationName.get()}-alpine-linux-amd64"
|
||||
artifact(stagedAlpineLinuxAmd64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedAlpineLinuxAmd64Executable)
|
||||
}
|
||||
pom {
|
||||
name = "${executableSpec.publicationName.get()}-alpine-linux-amd64"
|
||||
url = executableSpec.website
|
||||
description =
|
||||
executableSpec.documentationName.map { name ->
|
||||
"Native $name executable for linux/amd64 and statically linked to musl."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
create<MavenPublication>("windowsExecutableAmd64") {
|
||||
artifactId = "${executableSpec.publicationName.get()}-windows-amd64"
|
||||
artifact(stagedWindowsAmd64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "exe"
|
||||
builtBy(stagedWindowsAmd64Executable)
|
||||
}
|
||||
pom {
|
||||
name = "${executableSpec.publicationName.get()}-windows-amd64"
|
||||
url = executableSpec.website
|
||||
description =
|
||||
executableSpec.documentationName.map { name ->
|
||||
"Native $name executable for windows/amd64."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signing {
|
||||
project.afterEvaluate {
|
||||
sign(publishing.publications["linuxExecutableAarch64"])
|
||||
sign(publishing.publications["linuxExecutableAmd64"])
|
||||
sign(publishing.publications["macExecutableAarch64"])
|
||||
sign(publishing.publications["macExecutableAmd64"])
|
||||
sign(publishing.publications["alpineLinuxExecutableAmd64"])
|
||||
sign(publishing.publications["windowsExecutableAmd64"])
|
||||
}
|
||||
}
|
||||
129
buildSrc/src/main/kotlin/pklNativeLifecycle.gradle.kts
Normal file
129
buildSrc/src/main/kotlin/pklNativeLifecycle.gradle.kts
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
val assembleNativeMacOsAarch64 by tasks.registering { group = "build" }
|
||||
|
||||
val assembleNativeMacOsAmd64 by tasks.registering { group = "build" }
|
||||
|
||||
val assembleNativeLinuxAarch64 by tasks.registering { group = "build" }
|
||||
|
||||
val assembleNativeLinuxAmd64 by tasks.registering { group = "build" }
|
||||
|
||||
val assembleNativeAlpineLinuxAmd64 by tasks.registering { group = "build" }
|
||||
|
||||
val assembleNativeWindowsAmd64 by tasks.registering { group = "build" }
|
||||
|
||||
val testNativeMacOsAarch64 by tasks.registering { group = "verification" }
|
||||
|
||||
val testNativeMacOsAmd64 by tasks.registering { group = "verification" }
|
||||
|
||||
val testNativeLinuxAarch64 by tasks.registering { group = "verification" }
|
||||
|
||||
val testNativeLinuxAmd64 by tasks.registering { group = "verification" }
|
||||
|
||||
val testNativeAlpineLinuxAmd64 by tasks.registering { group = "verification" }
|
||||
|
||||
val testNativeWindowsAmd64 by tasks.registering { group = "verification" }
|
||||
|
||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||
|
||||
private fun <T : Task> Task.wraps(other: TaskProvider<T>) {
|
||||
dependsOn(other)
|
||||
outputs.files(other)
|
||||
}
|
||||
|
||||
val assembleNative by
|
||||
tasks.registering {
|
||||
group = "build"
|
||||
|
||||
if (!buildInfo.isCrossArchSupported && buildInfo.isCrossArch) {
|
||||
throw GradleException("Cross-arch builds are not supported on ${buildInfo.os.name}")
|
||||
}
|
||||
|
||||
when {
|
||||
buildInfo.os.isMacOsX && buildInfo.targetArch == "aarch64" -> {
|
||||
wraps(assembleNativeMacOsAarch64)
|
||||
}
|
||||
buildInfo.os.isMacOsX && buildInfo.targetArch == "amd64" -> {
|
||||
wraps(assembleNativeMacOsAmd64)
|
||||
}
|
||||
buildInfo.os.isLinux && buildInfo.targetArch == "aarch64" -> {
|
||||
wraps(assembleNativeLinuxAarch64)
|
||||
}
|
||||
buildInfo.os.isLinux && buildInfo.targetArch == "amd64" -> {
|
||||
if (buildInfo.musl) wraps(assembleNativeAlpineLinuxAmd64)
|
||||
else wraps(assembleNativeLinuxAmd64)
|
||||
}
|
||||
buildInfo.os.isWindows && buildInfo.targetArch == "amd64" -> {
|
||||
wraps(assembleNativeWindowsAmd64)
|
||||
}
|
||||
buildInfo.musl -> {
|
||||
throw GradleException("Building musl on ${buildInfo.os} is not supported")
|
||||
}
|
||||
else -> {
|
||||
throw GradleException(
|
||||
"Unsupported os/arch pair: ${buildInfo.os.name}/${buildInfo.targetArch}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val testNative by
|
||||
tasks.registering {
|
||||
group = "verification"
|
||||
|
||||
if (!buildInfo.isCrossArchSupported && buildInfo.isCrossArch) {
|
||||
throw GradleException("Cross-arch builds are not supported on ${buildInfo.os.name}")
|
||||
}
|
||||
|
||||
when {
|
||||
buildInfo.os.isMacOsX && buildInfo.targetArch == "aarch64" -> {
|
||||
dependsOn(testNativeMacOsAarch64)
|
||||
}
|
||||
buildInfo.os.isMacOsX && buildInfo.targetArch == "amd64" -> {
|
||||
dependsOn(testNativeMacOsAmd64)
|
||||
}
|
||||
buildInfo.os.isLinux && buildInfo.targetArch == "aarch64" -> {
|
||||
dependsOn(testNativeLinuxAarch64)
|
||||
}
|
||||
buildInfo.os.isLinux && buildInfo.targetArch == "amd64" -> {
|
||||
if (buildInfo.musl) dependsOn(testNativeAlpineLinuxAmd64)
|
||||
else dependsOn(testNativeLinuxAmd64)
|
||||
}
|
||||
buildInfo.os.isWindows && buildInfo.targetArch == "amd64" -> {
|
||||
dependsOn(testNativeWindowsAmd64)
|
||||
}
|
||||
buildInfo.musl -> {
|
||||
throw GradleException("Building musl on ${buildInfo.os} is not supported")
|
||||
}
|
||||
else -> {
|
||||
throw GradleException(
|
||||
"Unsupported os/arch pair: ${buildInfo.os.name}/${buildInfo.targetArch}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val checkNative by
|
||||
tasks.registering {
|
||||
group = "verification"
|
||||
dependsOn(testNative)
|
||||
}
|
||||
|
||||
val buildNative by
|
||||
tasks.registering {
|
||||
group = "build"
|
||||
dependsOn(assembleNative, checkNative)
|
||||
}
|
||||
@@ -1,6 +1,21 @@
|
||||
import org.gradle.api.publish.maven.tasks.GenerateMavenPom
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.Base64
|
||||
import org.gradle.api.publish.maven.tasks.GenerateMavenPom
|
||||
|
||||
plugins {
|
||||
`maven-publish`
|
||||
@@ -10,9 +25,7 @@ plugins {
|
||||
publishing {
|
||||
publications {
|
||||
components.findByName("java")?.let { javaComponent ->
|
||||
create<MavenPublication>("library") {
|
||||
from(javaComponent)
|
||||
}
|
||||
create<MavenPublication>("library") { from(javaComponent) }
|
||||
}
|
||||
withType<MavenPublication>().configureEach {
|
||||
pom {
|
||||
@@ -49,63 +62,66 @@ publishing {
|
||||
}
|
||||
}
|
||||
|
||||
val validatePom by tasks.registering {
|
||||
if (tasks.findByName("generatePomFileForLibraryPublication") == null) {
|
||||
return@registering
|
||||
}
|
||||
val generatePomFileForLibraryPublication by tasks.existing(GenerateMavenPom::class)
|
||||
val outputFile = layout.buildDirectory.file("validatePom") // dummy output to satisfy up-to-date check
|
||||
val validatePom by
|
||||
tasks.registering {
|
||||
if (tasks.findByName("generatePomFileForLibraryPublication") == null) {
|
||||
return@registering
|
||||
}
|
||||
val generatePomFileForLibraryPublication by tasks.existing(GenerateMavenPom::class)
|
||||
val outputFile =
|
||||
layout.buildDirectory.file("validatePom") // dummy output to satisfy up-to-date check
|
||||
|
||||
dependsOn(generatePomFileForLibraryPublication)
|
||||
inputs.file(generatePomFileForLibraryPublication.get().destination)
|
||||
outputs.file(outputFile)
|
||||
dependsOn(generatePomFileForLibraryPublication)
|
||||
inputs.file(generatePomFileForLibraryPublication.get().destination)
|
||||
outputs.file(outputFile)
|
||||
|
||||
doLast {
|
||||
outputFile.get().asFile.delete()
|
||||
doLast {
|
||||
outputFile.get().asFile.delete()
|
||||
|
||||
val pomFile = generatePomFileForLibraryPublication.get().destination
|
||||
assert(pomFile.exists())
|
||||
val pomFile = generatePomFileForLibraryPublication.get().destination
|
||||
assert(pomFile.exists())
|
||||
|
||||
val text = pomFile.readText()
|
||||
val text = pomFile.readText()
|
||||
|
||||
run {
|
||||
val unresolvedVersion = Regex("<version>.*[+,()\\[\\]].*</version>")
|
||||
val matches = unresolvedVersion.findAll(text).toList()
|
||||
if (matches.isNotEmpty()) {
|
||||
throw GradleException(
|
||||
"""
|
||||
run {
|
||||
val unresolvedVersion = Regex("<version>.*[+,()\\[\\]].*</version>")
|
||||
val matches = unresolvedVersion.findAll(text).toList()
|
||||
if (matches.isNotEmpty()) {
|
||||
throw GradleException(
|
||||
"""
|
||||
Found unresolved version selector(s) in generated POM:
|
||||
${matches.joinToString("\n") { it.groupValues[0] }}
|
||||
""".trimIndent()
|
||||
)
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||
if (buildInfo.isReleaseBuild) {
|
||||
val snapshotVersion = Regex("<version>.*-SNAPSHOT</version>")
|
||||
val matches = snapshotVersion.findAll(text).toList()
|
||||
if (matches.isNotEmpty()) {
|
||||
throw GradleException(
|
||||
"""
|
||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||
if (buildInfo.isReleaseBuild) {
|
||||
val snapshotVersion = Regex("<version>.*-SNAPSHOT</version>")
|
||||
val matches = snapshotVersion.findAll(text).toList()
|
||||
if (matches.isNotEmpty()) {
|
||||
throw GradleException(
|
||||
"""
|
||||
Found snapshot version(s) in generated POM of Pkl release version:
|
||||
${matches.joinToString("\n") { it.groupValues[0] }}
|
||||
""".trimIndent()
|
||||
)
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
outputFile.get().asFile.writeText("OK")
|
||||
}
|
||||
|
||||
outputFile.get().asFile.writeText("OK")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.publish {
|
||||
dependsOn(validatePom)
|
||||
}
|
||||
tasks.publish { dependsOn(validatePom) }
|
||||
|
||||
// Workaround for maven publish plugin not setting up dependencies correctly.
|
||||
// Taken from https://github.com/gradle/gradle/issues/26091#issuecomment-1798137734
|
||||
val dependsOnTasks = mutableListOf<String>()
|
||||
|
||||
tasks.withType<AbstractPublishToMaven>().configureEach {
|
||||
dependsOnTasks.add(name.replace("publish", "sign").replaceAfter("Publication", ""))
|
||||
dependsOn(dependsOnTasks)
|
||||
@@ -114,8 +130,10 @@ tasks.withType<AbstractPublishToMaven>().configureEach {
|
||||
signing {
|
||||
// provided as env vars `ORG_GRADLE_PROJECT_signingKey` and `ORG_GRADLE_PROJECT_signingPassword`
|
||||
// in CI.
|
||||
val signingKey = (findProperty("signingKey") as String?)
|
||||
?.let { Base64.getDecoder().decode(it).toString(StandardCharsets.US_ASCII) }
|
||||
val signingKey =
|
||||
(findProperty("signingKey") as String?)?.let {
|
||||
Base64.getDecoder().decode(it).toString(StandardCharsets.US_ASCII)
|
||||
}
|
||||
val signingPassword = findProperty("signingPassword") as String?
|
||||
if (signingKey != null && signingPassword != null) {
|
||||
useInMemoryPgpKeys(signingKey, signingPassword)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
// Copyright © $YEAR Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
/*
|
||||
* Copyright © $YEAR Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: main
|
||||
title: Main Project
|
||||
version: 0.26.0-dev
|
||||
prerelease: true
|
||||
version: 0.29.1
|
||||
prerelease: false
|
||||
nav:
|
||||
- nav.adoc
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
|
||||
|
||||
plugins {
|
||||
@@ -12,10 +27,7 @@ sourceSets {
|
||||
srcDir(file("modules/pkl-config-java/examples"))
|
||||
srcDir(file("modules/java-binding/examples"))
|
||||
}
|
||||
val kotlin = project.extensions
|
||||
.getByType<KotlinJvmProjectExtension>()
|
||||
.sourceSets[name]
|
||||
.kotlin
|
||||
val kotlin = project.extensions.getByType<KotlinJvmProjectExtension>().sourceSets[name].kotlin
|
||||
kotlin.srcDir(file("modules/kotlin-binding/examples"))
|
||||
}
|
||||
}
|
||||
@@ -25,12 +37,13 @@ dependencies {
|
||||
testImplementation(projects.pklConfigJava)
|
||||
testImplementation(projects.pklConfigKotlin)
|
||||
testImplementation(projects.pklCommonsTest)
|
||||
testImplementation(projects.pklParser)
|
||||
testImplementation(libs.junitEngine)
|
||||
testImplementation(libs.antlrRuntime)
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
inputs.files(fileTree("modules").matching {
|
||||
include("**/pages/*.adoc")
|
||||
}).withPropertyName("asciiDocFiles").withPathSensitivity(PathSensitivity.RELATIVE)
|
||||
inputs
|
||||
.files(fileTree("modules").matching { include("**/pages/*.adoc") })
|
||||
.withPropertyName("asciiDocFiles")
|
||||
.withPathSensitivity(PathSensitivity.RELATIVE)
|
||||
}
|
||||
|
||||
@@ -1,36 +1,46 @@
|
||||
# This is a Gradle generated file for dependency locking.
|
||||
# Manual edits can break the build and are not advised.
|
||||
# This file is expected to be part of source control.
|
||||
com.tunnelvisionlabs:antlr4-runtime:4.9.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.leangen.geantyref:geantyref:1.3.15=testRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy:1.14.16=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
|
||||
org.assertj:assertj-core:3.26.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.sdk:graal-sdk:23.0.2=testRuntimeClasspath
|
||||
org.graalvm.truffle:truffle-api:23.0.2=testRuntimeClasspath
|
||||
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.7.10=kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains:annotations:13.0=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.jupiter:junit-jupiter-engine:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.jupiter:junit-jupiter-params:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.platform:junit-platform-engine:1.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit:junit-bom:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
io.leangen.geantyref:geantyref:1.3.16=testRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy:1.15.11=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata
|
||||
org.assertj:assertj-core:3.27.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.polyglot:polyglot:24.1.2=testRuntimeClasspath
|
||||
org.graalvm.sdk:collections:24.1.2=testRuntimeClasspath
|
||||
org.graalvm.sdk:graal-sdk:24.1.2=testRuntimeClasspath
|
||||
org.graalvm.sdk:nativeimage:24.1.2=testRuntimeClasspath
|
||||
org.graalvm.sdk:word:24.1.2=testRuntimeClasspath
|
||||
org.graalvm.truffle:truffle-api:24.1.2=testRuntimeClasspath
|
||||
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-common:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:2.0.21=kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-native-prebuilt:2.0.21=kotlinNativeBundleConfiguration
|
||||
org.jetbrains.kotlin:kotlin-reflect:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.0.21=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.0.21=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains:annotations:13.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.13.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-engine:5.13.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-params:5.13.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.13.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-engine:1.13.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-launcher:1.13.3=testRuntimeClasspath
|
||||
org.junit:junit-bom:5.13.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.msgpack:msgpack-core:0.9.8=testRuntimeClasspath
|
||||
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.organicdesign:Paguro:3.10.3=testRuntimeClasspath
|
||||
org.snakeyaml:snakeyaml-engine:2.5=testRuntimeClasspath
|
||||
empty=annotationProcessor,apiDependenciesMetadata,archives,compile,compileClasspath,compileOnly,compileOnlyDependenciesMetadata,default,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtime,runtimeClasspath,runtimeOnlyDependenciesMetadata,testAnnotationProcessor,testApiDependenciesMetadata,testCompile,testCompileOnly,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDef,testKotlinScriptDefExtensions,testRuntime
|
||||
org.snakeyaml:snakeyaml-engine:2.10=testRuntimeClasspath
|
||||
empty=annotationProcessor,apiDependenciesMetadata,compileClasspath,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,runtimeClasspath,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions
|
||||
|
||||
20
docs/modules/ROOT/pages/evolution-and-roadmap.adoc
Normal file
20
docs/modules/ROOT/pages/evolution-and-roadmap.adoc
Normal file
@@ -0,0 +1,20 @@
|
||||
= Evolution and Roadmap
|
||||
|
||||
:uri-pkl-roadmap: https://github.com/orgs/apple/projects/12/views/1
|
||||
:uri-pkl-evolution: https://github.com/apple/pkl-evolution
|
||||
|
||||
== Evolution
|
||||
|
||||
Sometimes, a change to Pkl is large enough that it makes sense to create a proposal for the change so that it can be discussed in detail and vetted.
|
||||
|
||||
Pkl has a process for managing such designs in a repository called {uri-pkl-evolution}[Pkl Evolution].
|
||||
|
||||
== Roadmap
|
||||
|
||||
To discover what might be coming in future versions, reference the {uri-pkl-roadmap}[Pkl Roadmap] project on GitHub.
|
||||
|
||||
The roadmap describes estimates.
|
||||
The Pkl team aims to cut a release in February, June, and October of each year.
|
||||
If an item is not complete by the release cutoff date, the roadmap item may be bumped to the next release.
|
||||
|
||||
Additionally, as priorities change, it is possible that items can be moved around or backlogged.
|
||||
@@ -3,10 +3,10 @@
|
||||
// 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-no-suffix: 0.26.0
|
||||
:pkl-version-no-suffix: 0.29.1
|
||||
// tells whether pkl version corresponding to current git commit
|
||||
// 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
|
||||
|
||||
@@ -23,9 +23,9 @@ endif::[]
|
||||
|
||||
:uri-maven-docsite: https://central.sonatype.com
|
||||
|
||||
:uri-sonatype: https://s01.oss.sonatype.org/content/groups/public
|
||||
:uri-snapshot-repo: https://central.sonatype.com/repository/maven-snapshots
|
||||
|
||||
:uri-maven-repo: https://s01.oss.sonatype.org/content/groups/public
|
||||
:uri-maven-repo: https://central.sonatype.com/repository/maven-snapshots
|
||||
ifdef::is-release-version[]
|
||||
:uri-maven-repo: https://repo1.maven.org/maven2
|
||||
endif::[]
|
||||
@@ -68,15 +68,21 @@ endif::[]
|
||||
:uri-pkldoc-example: {uri-pkl-examples-tree}/pkldoc
|
||||
|
||||
:uri-stdlib-baseModule: {uri-pkl-stdlib-docs}/base
|
||||
:uri-stdlib-analyzeModule: {uri-pkl-stdlib-docs}/analyze
|
||||
:uri-stdlib-jsonnetModule: {uri-pkl-stdlib-docs}/jsonnet
|
||||
:uri-stdlib-reflectModule: {uri-pkl-stdlib-docs}/reflect
|
||||
:uri-stdlib-mathModule: {uri-pkl-stdlib-docs}/math
|
||||
:uri-stdlib-xmlModule: {uri-pkl-stdlib-docs}/xml
|
||||
:uri-stdlib-protobufModule: {uri-pkl-stdlib-docs}/protobuf
|
||||
:uri-stdlib-evaluatorSettingsModule: {uri-pkl-stdlib-docs}/EvaluatorSettings
|
||||
:uri-stdlib-evaluatorSettingsHttpClass: {uri-stdlib-evaluatorSettingsModule}/Http
|
||||
:uri-stdlib-Boolean: {uri-stdlib-baseModule}/Boolean
|
||||
:uri-stdlib-xor: {uri-stdlib-baseModule}/Boolean#xor()
|
||||
:uri-stdlib-implies: {uri-stdlib-baseModule}/Boolean#implies()
|
||||
:uri-stdlib-Any: {uri-stdlib-baseModule}/Any
|
||||
:uri-stdlib-String: {uri-stdlib-baseModule}/String
|
||||
:uri-stdlib-Collection: {uri-stdlib-baseModule}/Collection
|
||||
:uri-stdlib-StringToInt: {uri-stdlib-baseModule}/String#toInt()
|
||||
:uri-stdlib-Int: {uri-stdlib-baseModule}/Int
|
||||
:uri-stdlib-Float: {uri-stdlib-baseModule}/Float
|
||||
:uri-stdlib-Number: {uri-stdlib-baseModule}/Number
|
||||
@@ -134,8 +140,15 @@ endif::[]
|
||||
:uri-stdlib-Function3: {uri-stdlib-baseModule}/Function3
|
||||
:uri-stdlib-Function4: {uri-stdlib-baseModule}/Function4
|
||||
:uri-stdlib-Function5: {uri-stdlib-baseModule}/Function5
|
||||
:uri-stdlib-Bytes: {uri-stdlib-baseModule}/Bytes
|
||||
:uri-stdlib-Resource: {uri-stdlib-baseModule}/Resource
|
||||
:uri-stdlib-outputFiles: {uri-stdlib-baseModule}/ModuleOutput#files
|
||||
:uri-stdlib-FileOutput: {uri-stdlib-baseModule}/FileOutput
|
||||
|
||||
:uri-messagepack: https://msgpack.org/index.html
|
||||
:uri-messagepack-spec: https://github.com/msgpack/msgpack/blob/master/spec.md
|
||||
|
||||
:uri-pkl-roadmap: https://github.com/orgs/apple/projects/12/views/1
|
||||
|
||||
// TODO: figure out what the correct URL should be
|
||||
:uri-sonatype-snapshot-download: https://s01.oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=org.pkl-lang&v={pkl-artifact-version}
|
||||
|
||||
@@ -161,6 +161,24 @@ The array's length is the number of slots that are filled. For example, xref:{ur
|
||||
|
|
||||
|
|
||||
|
|
||||
|
||||
|link:{uri-stdlib-Function}[Function]
|
||||
|`0xE`
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
||||
|link:{uri-stdlib-Bytes}[Bytes]
|
||||
|`0xF`
|
||||
|link:{uri-messagepack-bin}[bin]
|
||||
|Binary contents
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|===
|
||||
|
||||
[[object-members]]
|
||||
|
||||
@@ -9,8 +9,8 @@ The first element of the array is a code that designates the message's type, enc
|
||||
The second element of the array is the message body, encoded as a map.
|
||||
|
||||
Messages are passed between the _client_ and the _server_.
|
||||
The _client_ is the host language (for example, the Swift application when using pkl-swift).
|
||||
The _server_ is the entity that provides controls for interacting with Pkl.
|
||||
When hosting Pkl (for example, the Swift application when using pkl-swift), the _client_ is the host program and the _server_ is the entity that provides controls for interacting with Pkl.
|
||||
When implementing an xref:language-reference:index.adoc#external-readers[external reader], the _client_ is the external reader process and the _server_ is the Pkl evaluator.
|
||||
|
||||
For example, in JSON representation:
|
||||
|
||||
@@ -75,7 +75,7 @@ requestId: Int
|
||||
/// API version of the CLI's `--allowed-modules` flag
|
||||
allowedModules: Listing<String>?
|
||||
|
||||
/// Regex patterns to dettermine which resources are allowed to be read.
|
||||
/// Regex patterns to determine which resources are allowed to be read.
|
||||
///
|
||||
/// API version of the CLI's `--allowed-resources` flag
|
||||
allowedResources: Listing<String>?
|
||||
@@ -130,7 +130,7 @@ class ClientResourceReader {
|
||||
/// The URI scheme this reader is responsible for reading.
|
||||
scheme: String
|
||||
|
||||
/// Tells whether the path part of ths URI has a
|
||||
/// Tells whether the path part of this URI has a
|
||||
/// [hier-part](https://datatracker.ietf.org/doc/html/rfc3986#section-3).
|
||||
///
|
||||
/// An example of a hierarchical URI is `file:///path/to/my/file`, where
|
||||
@@ -148,7 +148,7 @@ class ClientModuleReader {
|
||||
/// The URI scheme this reader is responsible for reading.
|
||||
scheme: String
|
||||
|
||||
/// Tells whether the path part of ths URI has a
|
||||
/// Tells whether the path part of this URI has a
|
||||
/// [hier-part](https://datatracker.ietf.org/doc/html/rfc3986#section-3).
|
||||
///
|
||||
/// An example of a hierarchical URI is `file:///path/to/my/file`, where
|
||||
@@ -199,12 +199,17 @@ class Http {
|
||||
/// PEM format certificates to trust when making HTTP requests.
|
||||
///
|
||||
/// If [null], Pkl will trust its own built-in certificates.
|
||||
caCertificates: Binary?
|
||||
caCertificates: Bytes? // <1>
|
||||
|
||||
/// Configuration of the HTTP proxy to use.
|
||||
///
|
||||
/// If [null], uses the operating system's proxy configuration.
|
||||
proxy: Proxy?
|
||||
|
||||
/// HTTP rewrites, from source prefix to target prefix.
|
||||
///
|
||||
/// Each rewrite must start with `http://` or `https://`, and must end with `/`.
|
||||
rewrites: Mapping<String, String>?
|
||||
}
|
||||
|
||||
/// Settings that control how Pkl talks to HTTP proxies.
|
||||
@@ -246,10 +251,8 @@ class Proxy {
|
||||
/// ```
|
||||
noProxy: Listing<String>(isDistinct)
|
||||
}
|
||||
|
||||
typealias Binary = Any // <1>
|
||||
----
|
||||
<1> link:{uri-messagepack-bin}[bin format] (not expressable in Pkl)
|
||||
<1> link:{uri-messagepack-bin}[bin format]
|
||||
|
||||
Example:
|
||||
[source,json5]
|
||||
@@ -347,14 +350,12 @@ requestId: Int
|
||||
evaluatorId: Int
|
||||
|
||||
/// The evaluation contents, if successful.
|
||||
result: Binary? // <1>
|
||||
result: Bytes? // <1>
|
||||
|
||||
/// A message detailing why evaluation failed.
|
||||
error: String?
|
||||
|
||||
typealias Binary = Any // <1>
|
||||
----
|
||||
<1> xref:binary-encoding.adoc[Pkl Binary Encoding] in link:{uri-messagepack-bin}[bin format] (not expressable in Pkl)
|
||||
<1> xref:binary-encoding.adoc[Pkl Binary Encoding] in link:{uri-messagepack-bin}[bin format]
|
||||
|
||||
[[log]]
|
||||
=== Log
|
||||
@@ -414,6 +415,8 @@ The response to <<read-resource-request>>.
|
||||
If successful, `contents` is set.
|
||||
Otherwise, `error` is set.
|
||||
|
||||
If neither is set, `contents` defaults to an empty byte array.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
/// A number identifying this request.
|
||||
@@ -423,14 +426,12 @@ requestId: Int
|
||||
evaluatorId: Int
|
||||
|
||||
/// The contents of the resource.
|
||||
contents: Binary? // <1>
|
||||
contents: Bytes? // <1>
|
||||
|
||||
/// The description of the error that occured when reading this resource.
|
||||
/// The description of the error that occurred when reading this resource.
|
||||
error: String?
|
||||
|
||||
typealias Binary = Any // <1>
|
||||
----
|
||||
<1> MessagePack's link:https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family[bin format family] (not expressable in Pkl)
|
||||
<1> MessagePack's link:https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family[bin format family]
|
||||
|
||||
[[read-module-request]]
|
||||
=== Read Module Request
|
||||
@@ -463,6 +464,8 @@ The response to <<read-module-request>>.
|
||||
If successful, `contents` is set.
|
||||
Otherwise, `error` is set.
|
||||
|
||||
If neither is set, `contents` defaults to an empty string.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
/// A number identifying this request.
|
||||
@@ -474,7 +477,7 @@ evaluatorId: Int
|
||||
/// The string contents of the module.
|
||||
contents: String?
|
||||
|
||||
/// The description of the error that occured when reading this resource.
|
||||
/// The description of the error that occurred when reading this resource.
|
||||
error: String?
|
||||
----
|
||||
|
||||
@@ -524,7 +527,7 @@ evaluatorId: Int
|
||||
/// The elements at the provided base path.
|
||||
pathElements: Listing<PathElement>?
|
||||
|
||||
/// The description of the error that occured when listing elements.
|
||||
/// The description of the error that occurred when listing elements.
|
||||
error: String?
|
||||
|
||||
class PathElement {
|
||||
@@ -582,7 +585,7 @@ evaluatorId: Int
|
||||
/// The elements at the provided base path.
|
||||
pathElements: Listing<PathElement>?
|
||||
|
||||
/// The description of the error that occured when listing elements.
|
||||
/// The description of the error that occurred when listing elements.
|
||||
error: String?
|
||||
|
||||
class PathElement {
|
||||
@@ -593,3 +596,96 @@ class PathElement {
|
||||
isDirectory: Boolean
|
||||
}
|
||||
----
|
||||
|
||||
[[initialize-module-reader-request]]
|
||||
=== Initialize Module Reader Request
|
||||
|
||||
Code: `0x2e` +
|
||||
Type: <<server-message,Server>> <<request-message,Request>>
|
||||
|
||||
Initialize an xref:language-reference:index.adoc#external-readers[External Module Reader].
|
||||
This message is sent to external reader processes the first time a module scheme it is registered for is read.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
/// A number identifying this request.
|
||||
requestId: Int
|
||||
|
||||
/// The module scheme to initialize.
|
||||
scheme: String
|
||||
----
|
||||
|
||||
[[initialize-module-reader-response]]
|
||||
=== Initialize Module Reader Response
|
||||
|
||||
Code: `0x2f` +
|
||||
Type: <<client-message,Client>> <<response-message,Response>>
|
||||
|
||||
Return the requested external module reader specification.
|
||||
The `spec` field should be set to `null` when the external process does not implement the requested module scheme.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
/// A number identifying this request.
|
||||
requestId: Int
|
||||
|
||||
/// Client-side module reader spec.
|
||||
///
|
||||
/// Null when the external process does not implement the requested module scheme.
|
||||
spec: ClientModuleReader?
|
||||
----
|
||||
|
||||
`ClientModuleReader` is defined above by <<create-evaluator-request,Create Evaluator Request>>.
|
||||
|
||||
[[initialize-resource-reader-request]]
|
||||
=== Initialize Resource Reader Request
|
||||
|
||||
Code: `0x30` +
|
||||
Type: <<server-message,Server>> <<request-message,Request>>
|
||||
|
||||
Initialize an xref:language-reference:index.adoc#external-readers[External Resource Reader].
|
||||
This message is sent to external reader processes the first time a resource scheme it is registered for is read.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
/// A number identifying this request.
|
||||
requestId: Int
|
||||
|
||||
/// The resource scheme to initialize.
|
||||
scheme: String
|
||||
----
|
||||
|
||||
[[initialize-resource-reader-response]]
|
||||
=== Initialize Resource Reader Response
|
||||
|
||||
Code: `0x31` +
|
||||
Type: <<client-message,Client>> <<response-message,Response>>
|
||||
|
||||
Return the requested external resource reader specification.
|
||||
The `spec` field should be set to `null` when the external process does not implement the requested resource scheme.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
/// A number identifying this request.
|
||||
requestId: Int
|
||||
|
||||
/// Client-side resource reader spec.
|
||||
///
|
||||
/// Null when the external process does not implement the requested resource scheme.
|
||||
spec: ClientResourceReader?
|
||||
----
|
||||
|
||||
`ClientResourceReader` is defined above by <<create-evaluator-request,Create Evaluator Request>>.
|
||||
|
||||
[[close-external-process]]
|
||||
=== Close External Process
|
||||
|
||||
Code: `0x32` +
|
||||
Type: <<server-message,Server>> <<one-way-message,One Way>>
|
||||
|
||||
Initiate graceful shutdown of the external reader process.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
/// This message has no properties.
|
||||
----
|
||||
|
||||
@@ -5,7 +5,7 @@ import org.pkl.core.ModuleSource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
// the pkl/pkl-examples repo has a similar example
|
||||
// the pkl-jvm-examples repo has a similar example
|
||||
public class JavaConfigExample {
|
||||
@Test
|
||||
public void usage() {
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
= Java Code Generator
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-pkl-codgen-java-maven-module: {uri-maven-docsite}/artifact/org.pkl-lang/pkl-codegen-java
|
||||
:uri-pkl-codegen-java-maven-module: {uri-maven-docsite}/artifact/org.pkl-lang/pkl-codegen-java
|
||||
|
||||
:uri-pkl-codegen-java-download: {uri-sonatype-snapshot-download}&a=pkl-cli-codegen-java&e=jar
|
||||
|
||||
ifdef::is-release-version[]
|
||||
:uri-pkl-codegen-java-download: {github-releases}/pkl-codegen-java
|
||||
endif::[]
|
||||
|
||||
The Java source code generator takes Pkl class definitions as an input, and generates corresponding Java classes with equally named properties.
|
||||
|
||||
@@ -23,11 +29,11 @@ See xref:pkl-gradle:index.adoc#installation[Installation] in the Gradle plugin c
|
||||
[[install-library]]
|
||||
=== Java Library
|
||||
|
||||
The `pkl-codegen-java` library is available {uri-pkl-codgen-java-maven-module}[from Maven Central].
|
||||
The `pkl-codegen-java` library is available {uri-pkl-codegen-java-maven-module}[from Maven Central].
|
||||
It requires Java 17 or higher.
|
||||
|
||||
ifndef::is-release-version[]
|
||||
NOTE: Snapshots are published to repository `{uri-sonatype}`.
|
||||
NOTE: Snapshots are published to repository `{uri-snapshot-repo}`.
|
||||
endif::[]
|
||||
|
||||
==== Gradle
|
||||
@@ -103,8 +109,41 @@ endif::[]
|
||||
[[install-cli]]
|
||||
=== CLI
|
||||
|
||||
The CLI is bundled with the Java library.
|
||||
As we do not currently ship the CLI as a self-contained Jar, we recommend to provision it with a Maven compatible build tool as shown in <<install-library>>.
|
||||
The CLI is available as a Java executable.
|
||||
|
||||
It works on multiple platforms, and requires a Java 17 (or higher) runtime on the system path.
|
||||
|
||||
To download:
|
||||
|
||||
[tabs]
|
||||
====
|
||||
macOS/Linux::
|
||||
+
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
curl -L -o pkl-codegen-java '{uri-pkl-codegen-java-download}'
|
||||
chmod +x pkl-codegen-java
|
||||
./pkl-codegen-java --version
|
||||
----
|
||||
|
||||
Windows::
|
||||
+
|
||||
[source,PowerShell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
Invoke-WebRequest '{uri-pkl-codegen-java-download}' -OutFile pkl-codegen-java.bat
|
||||
.\pkl-codegen-java --version
|
||||
----
|
||||
====
|
||||
|
||||
This should print something similar to:
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
pkl-codegen-java {pkl-version} (macOS 14.2, Java 17.0.10)
|
||||
----
|
||||
|
||||
[[codegen-java-usage]]
|
||||
== Usage
|
||||
@@ -123,10 +162,7 @@ For more information, refer to the Javadoc documentation.
|
||||
|
||||
=== CLI
|
||||
|
||||
As explained in <<install-cli,Installation>>, the CLI is bundled with the Java library.
|
||||
To run the CLI, execute the library Jar or its `org.pkl.codegen.java.Main` main class.
|
||||
|
||||
*Synopsis:* `java -cp <classpath> -jar pkl-codegen-java.jar [<options>] <modules>`
|
||||
*Synopsis:* `pkl-codegen-java [<options>] <modules>`
|
||||
|
||||
`<modules>`::
|
||||
The absolute or relative URIs of the modules to generate classes for.
|
||||
@@ -145,23 +181,27 @@ Flag that indicates to generate private final fields and public getter methods i
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (flag not set) +
|
||||
Flag that indicates to generate Javadoc based on doc comments for Pkl modules, classes, and properties.
|
||||
Flag that indicates to preserve Pkl doc comments by generating corresponding Javadoc comments.
|
||||
====
|
||||
|
||||
.--params-annotation
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `org.pkl.config.java.mapper.Named` +
|
||||
Fully qualified name of the annotation to use on constructor parameters.
|
||||
Default: `none` if `--generate-spring-boot` is set, `org.pkl.config.java.mapper.Named` otherwise +
|
||||
Fully qualified name of the annotation type to use for annotating constructor parameters with their name. +
|
||||
The specified annotation type must have a `value` parameter of type `String` or the generated code may not compile.
|
||||
If set to `none`, constructor parameters are not annotated.
|
||||
Whether and how constructor parameters should be annotated depends on the library that instantiates the generated classes.
|
||||
For Spring Boot applications, and for users of `pkl-config-java` compiling the generated classes with `-parameters`, no annotation is required.
|
||||
====
|
||||
|
||||
.--non-null-annotation
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `org.pkl.config.java.mapper.NonNull` +
|
||||
Fully qualified named of the annotation class to use for non-null types. +
|
||||
This annotation is required to have `java.lang.annotation.ElementType.TYPE_USE` as a `@Target`
|
||||
or it may generate code that does not compile.
|
||||
Fully qualified name of the annotation type to use for annotating non-null types. +
|
||||
The specified annotation type must be annotated with `@java.lang.annotation.Target(ElementType.TYPE_USE)`
|
||||
or the generated code may not compile.
|
||||
====
|
||||
|
||||
Common code generator options:
|
||||
@@ -176,4 +216,4 @@ include::../../pkl-cli/partials/cli-common-options.adoc[]
|
||||
== Full Example
|
||||
|
||||
For a ready-to-go example with full source code,
|
||||
see link:{uri-codegen-java-example}[codegen-java] in the _pkl/pkl-examples_ repository.
|
||||
see link:{uri-codegen-java-example}[codegen-java] in the _pkl-jvm-examples_ repository.
|
||||
|
||||
@@ -26,7 +26,14 @@ Flag that indicates to generate config classes for use with Spring Boot.
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (not set) +
|
||||
Whether to make generated classes implement `java.io.Serializable`.
|
||||
Flag that indicates to generate classes that implement `java.io.Serializable`.
|
||||
====
|
||||
|
||||
.--add-generated-annotation
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (not set) +
|
||||
Flag that indicates to add the `org.pkl.config.java.Generated` annotation to generated types.
|
||||
====
|
||||
|
||||
.--rename
|
||||
|
||||
@@ -6,7 +6,7 @@ import org.pkl.config.kotlin.to
|
||||
import org.pkl.core.ModuleSource
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
// the pkl/pkl-examples repo has a similar example
|
||||
// the pkl-jvm-examples repo has a similar example
|
||||
class KotlinConfigExample {
|
||||
@Test
|
||||
fun usage() {
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
= Kotlin Code Generator
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-pkl-codegen-kotlin-maven-module: {uri-maven-docsite}/artifact/org.pkl-lang/pkl-codegen-kotlin
|
||||
:uri-pkl-codegen-kotlin-download: {uri-sonatype-snapshot-download}&a=pkl-cli-codegen-kotlin&e=jar
|
||||
|
||||
ifdef::is-release-version[]
|
||||
:uri-pkl-codegen-kotlin-download: {github-releases}/pkl-codegen-kotlin
|
||||
endif::[]
|
||||
|
||||
The Kotlin source code generator reads Pkl classes and generates corresponding Kotlin classes with equally named properties.
|
||||
|
||||
@@ -83,8 +88,41 @@ To use the library in a Maven project, declare the following dependency:
|
||||
[[install-cli]]
|
||||
=== CLI
|
||||
|
||||
The CLI is bundled with the library.
|
||||
As we do not currently ship the CLI as a self-contained Jar, we recommend to provision it with a Maven compatible build tool as shown in <<install-library>>.
|
||||
The CLI is available as a Java executable.
|
||||
|
||||
It works on multiple platforms, and requires a Java 17 (or higher) runtime on the system path.
|
||||
|
||||
To download:
|
||||
|
||||
[tabs]
|
||||
====
|
||||
macOS/Linux::
|
||||
+
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
curl -L -o pkl-codegen-kotlin '{uri-pkl-codegen-kotlin-download}'
|
||||
chmod +x pkl-codegen-kotlin
|
||||
./pkl-codegen-kotlin --version
|
||||
----
|
||||
|
||||
Windows::
|
||||
+
|
||||
[source,PowerShell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
Invoke-WebRequest '{uri-pkl-codegen-kotlin-download}' -OutFile pkl-codegen-kotlin.bat
|
||||
.\pkl-codegen-kotlin --version
|
||||
----
|
||||
====
|
||||
|
||||
This should print something similar to:
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
pkl-codegen-kotlin {pkl-version} (macOS 14.2, Java 17.0.10)
|
||||
----
|
||||
|
||||
[[usage]]
|
||||
== Usage
|
||||
@@ -103,10 +141,7 @@ For more information, refer to the KDoc documentation.
|
||||
|
||||
=== CLI
|
||||
|
||||
As mentioned in <<install-cli,Installation>>, the CLI is bundled with the library.
|
||||
To run the CLI, execute the library Jar or its `org.pkl.codegen.kotlin.Main` main class.
|
||||
|
||||
*Synopsis:* `java -cp <classpath> -jar pkl-codegen-kotlin.jar [<options>] <modules>`
|
||||
*Synopsis:* `pkl-codegen-kotlin [<options>] <modules>`
|
||||
|
||||
`<modules>`::
|
||||
The absolute or relative URIs of the modules to generate classes for.
|
||||
@@ -118,7 +153,7 @@ Relative URIs are resolved against the working directory.
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (flag not set) +
|
||||
Flag that indicates to generate Kdoc based on doc comments for Pkl modules, classes, and properties.
|
||||
Flag that indicates to preserve Pkl doc comments by generating corresponding KDoc comments.
|
||||
====
|
||||
|
||||
Common code generator options:
|
||||
@@ -133,4 +168,4 @@ include::../../pkl-cli/partials/cli-common-options.adoc[]
|
||||
== Full Example
|
||||
|
||||
For a ready-to-go example with full source code,
|
||||
see link:{uri-codegen-kotlin-example}[codegen-kotlin] in the _pkl/pkl-examples_ repository.
|
||||
see link:{uri-codegen-kotlin-example}[codegen-kotlin] in the _pkl-jvm-examples_ repository.
|
||||
|
||||
@@ -116,7 +116,7 @@ include::{examplesdir}/KotlinConfigExample.kt[tags=nullable]
|
||||
Converting to `String` would result in a `ConversionException`.
|
||||
|
||||
For a ready-to-go example with full source code,
|
||||
see link:{uri-config-kotlin-example}[config-kotlin] in the _pkl/pkl-examples_ repository.
|
||||
see link:{uri-config-kotlin-example}[config-kotlin] in the _pkl-jvm-examples_ repository.
|
||||
|
||||
== Further Information
|
||||
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-common-mark: https://commonmark.org/
|
||||
:uri-newspeak: https://newspeaklanguage.org
|
||||
:uri-antlr4: https://www.antlr.org
|
||||
:uri-prototypical-inheritance: https://en.wikipedia.org/wiki/Prototype-based_programming
|
||||
:uri-double-precision: https://en.wikipedia.org/wiki/Double-precision_floating-point_format
|
||||
:uri-progressive-disclosure: https://en.wikipedia.org/wiki/Progressive_disclosure
|
||||
:uri-javadoc-Pattern: https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html
|
||||
:uri-github-PklLexer: {uri-github-tree}/pkl-core/src/main/antlr/PklLexer.g4
|
||||
:uri-github-PklParser: {uri-github-tree}/pkl-core/src/main/antlr/PklParser.g4
|
||||
:uri-github-PklLexer: {uri-github-tree}/pkl-core/src/main/java/org/pkl/core/parser/Lexer.java
|
||||
:uri-pkl-core-ModuleSchema: {uri-pkl-core-main-sources}/ModuleSchema.java
|
||||
:uri-pkl-core-SecurityManager: {uri-pkl-core-main-sources}/SecurityManager.java
|
||||
:uri-pkl-core-ResourceReader: {uri-pkl-core-main-sources}/resource/ResourceReader.java
|
||||
@@ -915,6 +913,7 @@ pigeon = new Dynamic { // <1>
|
||||
==== Hidden Properties
|
||||
|
||||
A property with the modifier `hidden` is omitted from the rendered output and object conversions.
|
||||
Hidden properties are also ignored when evaluating equality or hashing (e.g. for `Mapping` or `Map` keys).
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
@@ -933,12 +932,19 @@ pigeon = new Bird { // <3>
|
||||
pigeonInIndex = pigeon.nameAndLifespanInIndex // <4>
|
||||
|
||||
pigeonDynamic = pigeon.toDynamic() // <5>
|
||||
|
||||
favoritePigeon = (pigeon) {
|
||||
nameAndLifespanInIndex = "Bettie, \(lifespan)"
|
||||
}
|
||||
|
||||
samePigeon = pigeon == favoritePigeon // <6>
|
||||
----
|
||||
<1> Properties defined as `hidden` are accessible on any `Bird` instance, but not output by default.
|
||||
<2> Non-hidden properties can refer to hidden properties as usual.
|
||||
<3> `pigeon` is an object with _four_ properties, but is rendered with _three_ properties.
|
||||
<4> Accessing a `hidden` property from outside the class and object is like any other property.
|
||||
<5> Object conversions omit hidden properties, so the resulting `Dynamic` has three properties.
|
||||
<6> Objects that differ only in `hidden` property values are considered equal
|
||||
|
||||
Invoking Pkl on this file produces the following result.
|
||||
|
||||
@@ -955,6 +961,12 @@ pigeonDynamic {
|
||||
lifespan = 8
|
||||
nameSignWidth = 9
|
||||
}
|
||||
favoritePigeon {
|
||||
name = "Pigeon"
|
||||
lifespan = 8
|
||||
nameSignWidth = 9
|
||||
}
|
||||
samePigeon = true
|
||||
----
|
||||
|
||||
==== Local properties
|
||||
@@ -1047,7 +1059,7 @@ class Penguin extends Bird {
|
||||
<2> Error: modifier `fixed` cannot be applied to property `name`.
|
||||
|
||||
The `fixed` modifier is useful for defining properties that are meant to be derived from other properties.
|
||||
In the following snippet, the property `result` is not meant to be assigned to, because it is derived
|
||||
In the following snippet, the property `wingspanWeightRatio` is not meant to be assigned to, because it is derived
|
||||
from other properties.
|
||||
|
||||
[source%parsed,{pkl}]
|
||||
@@ -1992,7 +2004,8 @@ pigeon: ParentBird = new {
|
||||
[[methods]]
|
||||
== Methods
|
||||
|
||||
Modules and classes can define methods.
|
||||
Pkl methods can be defined on classes and modules using the `function` keyword.
|
||||
Methods may access properties of their containing type.
|
||||
Submodules and subclasses can override them.
|
||||
|
||||
Like Java and most other object-oriented languages, Pkl uses _single dispatch_ -- methods are dynamically dispatched based on the receiver's runtime type.
|
||||
@@ -2021,6 +2034,15 @@ greeting2 = greetPigeon(parrot) // <4>
|
||||
<3> Call instance method on `pigeon`.
|
||||
<4> Call module method (on `this`).
|
||||
|
||||
Like other object-oriented languages, methods defined on extended classes and modules may be overridden.
|
||||
The parent type's method may be called via the <<super-keyword,`super` keyword>>.
|
||||
|
||||
NOTE: Methods do not support named parameters or default parameter values.
|
||||
The xref:blog:ROOT:class-as-a-function.adoc[Class-as-a-function] pattern may be a suitable replacement.
|
||||
|
||||
TIP: In most cases, methods without parameters should not be defined.
|
||||
Instead, use <<fixed-properties,`fixed` properties>> on the module or class.
|
||||
|
||||
[[modules]]
|
||||
== Modules
|
||||
|
||||
@@ -2132,6 +2154,9 @@ Optionally, the SHA-256 checksum of the package can also be specified:
|
||||
Packages can be managed as dependencies within a _project_.
|
||||
For more details, consult the <<projects,project>> section of the language reference.
|
||||
|
||||
Packages can also be downloaded from a mirror.
|
||||
For more details, consult the <<mirroring_packages>> section of the language reference.
|
||||
|
||||
==== Standard Library URI
|
||||
|
||||
Example: `+pkl:math+`
|
||||
@@ -2552,7 +2577,7 @@ the following security checks are performed:
|
||||
* The target module URI is checked against the module allowlist (`--allowed-modules`).
|
||||
* The source and target modules' _trust levels_ are determined and compared.
|
||||
|
||||
For access to be granted, the source module's trust level must be higher than or equal to the target module's trust level.
|
||||
For access to be granted, the source module's trust level must be greater than or equal to the target module's trust level.
|
||||
By default, there are five trust levels, listed from highest to lowest:
|
||||
|
||||
. `repl:` modules (code evaluated in the REPL)
|
||||
@@ -2695,7 +2720,7 @@ quota:
|
||||
disk: 20 GB
|
||||
----
|
||||
|
||||
In addition to _type_ based converters, renderers also support _path_ based converters:
|
||||
In addition to _class_-based converters, renderers also support _path_-based converters:
|
||||
|
||||
[source%parsed,{pkl}]
|
||||
----
|
||||
@@ -3156,6 +3181,7 @@ pkl: TRACE: num1 * num2 = 672 (at file:///some/module.pkl, line 42)
|
||||
|
||||
This section discusses language features that are generally more relevant to template and library authors than template consumers.
|
||||
|
||||
<<meaning-of-new,Meaning of `new`>> +
|
||||
<<let-expressions,Let Expressions>> +
|
||||
<<type-tests,Type Tests>> +
|
||||
<<type-casts,Type Casts>> +
|
||||
@@ -3171,13 +3197,174 @@ This section discusses language features that are generally more relevant to tem
|
||||
<<for-generators,For Generators>> +
|
||||
<<spread-syntax,Spread Syntax>> +
|
||||
<<member-predicates,Member Predicates (`[[...]]`)>> +
|
||||
<<this-keyword,`this` Keyword>> +
|
||||
<<outer-keyword,`outer` Keyword>> +
|
||||
<<super-keyword,`super` Keyword>> +
|
||||
<<module-keyword,`module` Keyword>> +
|
||||
<<glob-patterns,Glob Patterns>> +
|
||||
<<doc-comments,Doc Comments>> +
|
||||
<<name-resolution,Name Resolution>> +
|
||||
<<grammar-definition,Grammar Definition>> +
|
||||
<<reserved-keywords,Reserved Keywords>> +
|
||||
<<blank-identifiers,Blank Identifiers>> +
|
||||
<<projects,Projects>>
|
||||
<<projects,Projects>> +
|
||||
<<external-readers,External Readers>> +
|
||||
<<mirroring_packages,Mirroring packages>>
|
||||
|
||||
[[meaning-of-new]]
|
||||
=== Meaning of `new`
|
||||
|
||||
Objects in Pkl always <<amending-objects, amends>> _some_ value.
|
||||
The `new` keyword is a special case of amending where a contextual value is amended.
|
||||
In Pkl, there are two forms of `new` objects:
|
||||
|
||||
* `new` with explicit type information, for example, `new Foo {}`.
|
||||
* `new` without type information, for example, `new {}`.
|
||||
|
||||
==== Type defaults
|
||||
|
||||
To understand instantiation cases without explicit parent or type information, it's important to first understand implicit default values.
|
||||
When a property is declared in a module or class but is not provided an explicit default value, the property's default value becomes the type's default value.
|
||||
Similarly, when `Listing` and `Mapping` types are declared with explicit type arguments for their element or value, their `default` property amends that declared type.
|
||||
When `Listing` and `Mapping` types are declared without type arguments, their `default` property amends an empty `Dynamic` object.
|
||||
Some types, including `Pair` and primitives like `String`, `Number`, and `Boolean` have no default value; attempting to render such a property results in the error "Tried to read property `<name>` but its value is undefined".
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
class Bird {
|
||||
name: String = "polly"
|
||||
}
|
||||
|
||||
bird: Bird // <1>
|
||||
birdListing: Listing<Bird> // <2>
|
||||
birdMapping: Mapping<String, Bird> // <3>
|
||||
----
|
||||
<1> Without an explicit default value, this property has default value `new Bird { name = "polly" }`
|
||||
<2> With an explicit element type argument, this property's default value is equivalent to `new Listing<Bird> { default = (_) -> new Bird { name = "polly" } }`
|
||||
<3> With an explicit value type argument, this property's default value is equivalent to `new Mapping<String, Bird> { default = (_) -> new Bird { name = "polly" } }`
|
||||
|
||||
==== Explicitly Typed `new`
|
||||
|
||||
Instantiating an object with `new <type>` results in a value that amends the specified type's default value.
|
||||
Notably, creating a `Listing` element or assigning a `Mapping` entry value with an explicitly typed `new` ignores the object's `default` value.
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
class Bird {
|
||||
/// The name of the bird
|
||||
name: String
|
||||
|
||||
/// Whether this is a bird of prey or not.
|
||||
isPredatory: Boolean?
|
||||
}
|
||||
|
||||
newProperty = new Bird { // <1>
|
||||
name = "Warbler"
|
||||
}
|
||||
|
||||
someListing = new Listing<Bird> {
|
||||
default {
|
||||
isPredatory = true
|
||||
}
|
||||
new Bird { // <2>
|
||||
name = "Sand Piper"
|
||||
}
|
||||
}
|
||||
|
||||
someMapping = new Mapping<String, Bird> {
|
||||
default {
|
||||
isPredatory = true
|
||||
}
|
||||
["Penguin"] = new Bird { // <3>
|
||||
name = "Penguin"
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> Assigning a `new` explicitly-typed value to a property.
|
||||
<2> Adding an `new` explicitly-typed `Listing` element.
|
||||
The value will not have property `isPredatory = true` as the `default` property of the `Listing` is not used.
|
||||
<3> Assigning a `new` explicitly-typed value to a `Mapping` entry.
|
||||
The value will not have property `isPredatory = true` as the `default` property of the `Mapping` is not used.
|
||||
|
||||
==== Implicitly Typed `new`
|
||||
|
||||
When using the implicitly typed `new` invocation, there is no explicit parent value to amend.
|
||||
In these cases, Pkl infers the amend operation's parent value based on context:
|
||||
|
||||
* When assigning to a declared property, the property's default value is amended (<<amend-null, including `null`>>).
|
||||
If there is no type associated with the property, an empty `Dynamic` object is amended.
|
||||
* When assigning to an entry (e.g. a `Mapping` member) or element (e.g. a `Listing` member), the enclosing object's `default` property is applied to the corresponding index or key, respectively, to produce the value to be amended.
|
||||
* In other cases, evaluation fails with the error message "Cannot tell which parent to amend".
|
||||
|
||||
The type annotation of a <<methods,method>> parameter is not used for inference.
|
||||
In this case, the argument's type should be specified explicitly.
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
class Bird {
|
||||
name: String
|
||||
|
||||
function listHatchlings(items: Listing<String>): Listing<String> = new {
|
||||
for (item in items) {
|
||||
"\(name):\(item)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedProperty: Bird = new { // <1>
|
||||
name = "Swift"
|
||||
}
|
||||
|
||||
untypedProperty = new { // <2>
|
||||
hello = "world"
|
||||
}
|
||||
|
||||
typedListing: Listing<Bird> = new {
|
||||
new { // <3>
|
||||
name = "Kite"
|
||||
}
|
||||
}
|
||||
|
||||
untypedListing: Listing = new {
|
||||
new { // <4>
|
||||
hello = "there"
|
||||
}
|
||||
}
|
||||
|
||||
typedMapping: Mapping<String, Bird> = new {
|
||||
default { entryKey ->
|
||||
name = entryKey
|
||||
}
|
||||
["Saltmarsh Sparrow"] = new { // <5>
|
||||
name = "Sharp-tailed Sparrow"
|
||||
}
|
||||
}
|
||||
|
||||
amendedMapping = (typedMapping) {
|
||||
["Saltmarsh Sparrow"] = new {} // <6>
|
||||
}
|
||||
|
||||
class Aviary {
|
||||
birds: Listing<Bird> = new {
|
||||
new { name = "Osprey" }
|
||||
}
|
||||
}
|
||||
|
||||
aviary: Aviary = new {
|
||||
birds = new { // <7>
|
||||
new { name = "Kiwi" }
|
||||
}
|
||||
}
|
||||
|
||||
swiftHatchlings = typedProperty.listHatchlings(new { "Poppy"; "Chirpy" }) // <8>
|
||||
----
|
||||
<1> Assignment to a property with an explicitly declared type, amending `new Bird {}`.
|
||||
<2> Assignment to an undeclared property in module context, amending `new Dynamic {}`.
|
||||
<3> `Listing` element creation, amending implicit `default`, `new Bird {}`.
|
||||
<4> `Listing` element creation, amending implicit `default`, `new Dynamic {}`.
|
||||
<5> `Mapping` value assignment, amending the result of applying `default` to `"Saltmarsh Sparrow"`, `new Bird { name = "Saltmarsh Sparrow" }`.
|
||||
<6> `Mapping` value assignment _replacing_ the parent's entry, amending the result of applying `default` to `"Saltmarsh Sparrow"`, `new Bird { name = "Saltmarsh Sparrow" }`.
|
||||
<7> Amending the property default value `new Listing { new Bird { name = "Osprey" } }`; the result contains both birds.
|
||||
<8> Error: Cannot tell which parent to amend.
|
||||
|
||||
[[let-expressions]]
|
||||
=== Let Expressions
|
||||
@@ -3200,10 +3387,11 @@ Here is an example:
|
||||
|
||||
[source%tested,{pkl}]
|
||||
----
|
||||
birdDiets = let (diets = List("Seeds", "Berries", "Mice"))
|
||||
List(diets[2], diets[0]) // <1>
|
||||
birdDiets =
|
||||
let (diets = List("Seeds", "Berries", "Mice"))
|
||||
List(diets[2], diets[0]) // <1>
|
||||
----
|
||||
<1> result: `List("Mice", "Seeds")`
|
||||
<1> result: `birdDiets = List("Mice", "Seeds")`
|
||||
|
||||
`let` expressions serve two purposes:
|
||||
|
||||
@@ -3214,20 +3402,22 @@ List(diets[2], diets[0]) // <1>
|
||||
|
||||
[source%tested,{pkl}]
|
||||
----
|
||||
birdDiets = let (diets: List<String> = List("Seeds", "Berries", "Mice"))
|
||||
diets[2] + diets[0] // <1>
|
||||
birdDiets =
|
||||
let (diets: List<String> = List("Seeds", "Berries", "Mice"))
|
||||
diets[2] + diets[0] // <1>
|
||||
----
|
||||
<1> result: `List("Mice", "Seeds")`
|
||||
<1> result: `birdDiets = List("Mice", "Seeds")`
|
||||
|
||||
`let` expressions can be stacked:
|
||||
|
||||
[source%tested,{pkl}]
|
||||
----
|
||||
birdDiets = let (birds = List("Pigeon", "Barn owl", "Parrot"))
|
||||
let (diet = List("Seeds", "Mice", "Berries"))
|
||||
birds.zip(diet) // <1>
|
||||
birdDiets =
|
||||
let (birds = List("Pigeon", "Barn owl", "Parrot"))
|
||||
let (diet = List("Seeds", "Mice", "Berries"))
|
||||
birds.zip(diet) // <1>
|
||||
----
|
||||
<1> result: `List(Pair("Pigeon", "Seeds"), Pair("Barn owl", "Mice"), Pair("Parrot", "Berries"))`
|
||||
<1> result: `birdDiets = List(Pair("Pigeon", "Seeds"), Pair("Barn owl", "Mice"), Pair("Parrot", "Berries"))`
|
||||
|
||||
[[type-tests]]
|
||||
=== Type Tests
|
||||
@@ -3357,9 +3547,7 @@ res6 = list.map((n) -> n * 3) // <6>
|
||||
[[sets]]
|
||||
=== Sets
|
||||
|
||||
A value of type link:{uri-stdlib-Set}[Set] is an ordered collection of unique _elements_.
|
||||
|
||||
A set's elements are eagerly evaluated.
|
||||
A value of type link:{uri-stdlib-Set}[Set] is a collection of unique _elements_.
|
||||
|
||||
Sets are constructed with the `Set()` methodfootnote:soft-keyword[]:
|
||||
|
||||
@@ -3375,6 +3563,20 @@ res4 = Set(1, "x", 5.min, List(1, 2, 3)) // <4>
|
||||
<3> result: same set of length 3
|
||||
<4> result: heterogeneous set that contains a list as its last element
|
||||
|
||||
Sets retain the order of elements when constructed, which impacts how they are iterated over.
|
||||
However, this order is not considered when determining equality of two sets.
|
||||
|
||||
[source%tested,{pkl}]
|
||||
----
|
||||
res1 = Set(4, 3, 2)
|
||||
res2 = res1.first // <1>
|
||||
res3 = res1.toListing() // <2>
|
||||
res4 = Set(2, 3, 4) == res1 // <3>
|
||||
----
|
||||
<1> result: `4`
|
||||
<2> result: `new Listing { 4; 3; 2 }`
|
||||
<3> result: `true`
|
||||
|
||||
To compute the union of sets, use the `+` operator:
|
||||
|
||||
[source%tested,{pkl-expr}]
|
||||
@@ -3402,7 +3604,7 @@ res4 = set.intersect(Set(3, 9, 2)) // <4>
|
||||
[[maps]]
|
||||
=== Maps
|
||||
|
||||
A value of type link:{uri-stdlib-Map}[Map] is an ordered collection of _values_ indexed by _key_.
|
||||
A value of type link:{uri-stdlib-Map}[Map] is a collection of _values_ indexed by _key_.
|
||||
|
||||
A map's key-value pairs are called its _entries_.
|
||||
Keys and values are eagerly evaluated.
|
||||
@@ -3437,6 +3639,20 @@ Any Pkl value can be used as a map key:
|
||||
Map(new Dynamic { name = "Pigeon" }, 10.gb)
|
||||
----
|
||||
|
||||
Maps retain the order of entries when constructed, which impacts how they are iterated over.
|
||||
However, this order is not considered when determining equality of two maps.
|
||||
|
||||
[source%tested,{pkl}]
|
||||
----
|
||||
res1 = Map(2, "hello", 1, "world")
|
||||
res2 = res1.entries.first // <1>
|
||||
res3 = res1.toMapping() // <2>
|
||||
res4 = res1 == Map(1, "world", 2, "hello") // <3>
|
||||
----
|
||||
<1> result: `Pair(2, "hello")`
|
||||
<2> result: `new Mapping { [2] = "hello"; [1] = "world" }`
|
||||
<3> result: `true`
|
||||
|
||||
To merge maps, use the `+` operator:
|
||||
|
||||
[source%tested,{pkl}]
|
||||
@@ -3472,6 +3688,41 @@ res5 = map.getOrNull("Falcon") // <5>
|
||||
<4> result: `2`
|
||||
<5> result: `null`
|
||||
|
||||
[[bytes]]
|
||||
=== Bytes
|
||||
|
||||
A value of type `Bytes` is a sequence of `UInt8` elements.
|
||||
|
||||
`Bytes` can be constructed by passing byte values into the constructor.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
bytes1 = Bytes(0xff, 0x00, 0x3f) // <1>
|
||||
bytes2 = Bytes() // <2>
|
||||
----
|
||||
<1> Result: a `Bytes` with 3 elements
|
||||
<2> Result: an empty `Bytes`
|
||||
|
||||
`Bytes` can also be constructed from a base64-encoded string, via `base64DecodedBytes`:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
bytes3 = "cGFycm90".base64DecodedBytes // <1>
|
||||
----
|
||||
<1> Result: `Bytes(112, 97, 114, 114, 111, 116)`
|
||||
|
||||
==== `Bytes` vs `List<UInt8>`
|
||||
|
||||
`Bytes` is similar to `List<UInt8>` in that they are both sequences of `UInt8` elements.
|
||||
However, they are semantically distinct.
|
||||
`Bytes` represent binary data, and is typically rendered differently.
|
||||
For example, they are rendered as `<data>` tags when using `PListRenderer`.
|
||||
|
||||
`Bytes` also have different performance characteristics; a value of type `Bytes` tends to be managed as a contiguous memory block.
|
||||
Thus, they are more compact and consume less memory.
|
||||
However, they are not optimized for transformations.
|
||||
For example, given two values of size `M` and `N`, concatenating two `Bytes` values allocates O(M + N) space, whereas concatenating two `List` values allocates O(1) space.
|
||||
|
||||
[[regular-expressions]]
|
||||
=== Regular Expressions
|
||||
|
||||
@@ -3721,6 +3972,7 @@ bird2: Bird? = null // <2>
|
||||
The only class types that admit `null` values despite not ending in `?` are `Any` and `Null`.
|
||||
(`Null` is not very useful as a type because it _only_ admits `null` values.)
|
||||
`Any?` and `Null?` are equivalent to `Any` and `Null`, respectively.
|
||||
In some languages, nullable types are also known as _optional types_.
|
||||
|
||||
[[generic-types]]
|
||||
==== Generic Types
|
||||
@@ -4458,6 +4710,10 @@ The following types are iterable:
|
||||
|entry key (`Key`)
|
||||
|entry value (`Value`)
|
||||
|
||||
|`Bytes`
|
||||
|element index (`Int`)
|
||||
|element value (`UInt8`)
|
||||
|
||||
|`Listing<Element>`
|
||||
|element index (`Int`)
|
||||
|element value (`Element`)
|
||||
@@ -4538,6 +4794,9 @@ The following table describes how different iterables turn into object members:
|
||||
|
||||
| `IntSeq`
|
||||
| Element
|
||||
|
||||
| `Bytes`
|
||||
| Element
|
||||
|===
|
||||
|
||||
These types can only be spread into enclosing objects that support that member type.
|
||||
@@ -4560,7 +4819,7 @@ oldPets {
|
||||
}
|
||||
|
||||
newPets {
|
||||
...cast
|
||||
...oldPets
|
||||
["Pigeon"] = "Toby the Pigeon" // <1>
|
||||
}
|
||||
----
|
||||
@@ -4620,6 +4879,161 @@ The predicate, enclosed in double brackets (`\[[...]]`), is matched against each
|
||||
Within the predicate, `this` refers to the member that the predicate is matched against.
|
||||
Matching members are amended (`{ ... }`) or overridden (`= <new-value>`).
|
||||
|
||||
[[this-keyword]]
|
||||
=== `this` keyword
|
||||
|
||||
Normally, the `this` keyword references the enclosing object's receiver.
|
||||
|
||||
Example:
|
||||
[source,pkl]
|
||||
----
|
||||
bird {
|
||||
eatsInsects = this is InsectavorousBird
|
||||
}
|
||||
----
|
||||
|
||||
When used inside a <<type-constraints,type constraint>>, `this` refers to the value being tested.
|
||||
|
||||
Example:
|
||||
[source,pkl]
|
||||
----
|
||||
port: UInt16(this > 1000)
|
||||
----
|
||||
|
||||
When used inside a <<member-predicates,member predicate>>, `this` refers to the value being matched against.
|
||||
|
||||
Example:
|
||||
[source,pkl]
|
||||
----
|
||||
animals {
|
||||
[[this is Bird]] {
|
||||
canFly = true
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
[[receiver]]
|
||||
==== Receiver
|
||||
|
||||
The receiver is the bottom-most object in the <<prototype-chain>>.
|
||||
That means that, within the context of an amending object, the reciever is the amending object.
|
||||
|
||||
Example:
|
||||
[source,pkl]
|
||||
----
|
||||
hidden lawyerBird {
|
||||
title = "\(this.name), Esq."
|
||||
}
|
||||
|
||||
polly = (lawyerBird) {
|
||||
name = "Polly" // <1>
|
||||
}
|
||||
----
|
||||
<1> Polly has title `"Polly, Esq."`.
|
||||
|
||||
[[outer-keyword]]
|
||||
=== `outer` keyword
|
||||
|
||||
The `outer` keyword references the <<receiver,receiver>> of the immediately outer lexical object.
|
||||
|
||||
It can be useful to disambiguate a lookup that might otherwise resolve elsewhere.
|
||||
|
||||
Example:
|
||||
[source%tested,pkl]
|
||||
----
|
||||
foo {
|
||||
bar = "bar"
|
||||
qux {
|
||||
bar = outer.bar // <1>
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> References `bar` one level higher.
|
||||
|
||||
Note that `outer` cannot be chained.
|
||||
In order to reference a value more than one level higher, a typical pattern is to declare a local property at that level.
|
||||
|
||||
For example:
|
||||
|
||||
[source%parsed,pkl]
|
||||
----
|
||||
foo {
|
||||
local self = this
|
||||
bar {
|
||||
baz {
|
||||
qux = self.qux
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
[[super-keyword]]
|
||||
=== `super` keyword
|
||||
|
||||
The `super` keyword references the parent object in the <<prototype-chain,prototype chain>>.
|
||||
|
||||
When used within a class, it refers to the superclass's prototype.
|
||||
When used within an object, it refers to the parent object in the amends chain.
|
||||
|
||||
Example:
|
||||
[source%tested,pkl]
|
||||
----
|
||||
bird = new { name = "Quail" }
|
||||
|
||||
bird2 = (bird) { name = "Ms. \(super.name)" } // <1>
|
||||
|
||||
abstract class Bird {
|
||||
foods: Listing<String>
|
||||
|
||||
function canEat(food: String): Boolean = foods.contains(food)
|
||||
}
|
||||
|
||||
class InsectavorousBird extends Bird {
|
||||
function canEat(food: String) =
|
||||
super.canEat(food) || food == "insect" // <2>
|
||||
}
|
||||
----
|
||||
<1> Result: `"Ms. Quail"`
|
||||
<2> Calls parent class method `canEat()`
|
||||
|
||||
The `super` keyword must be followed by property/method access, or subscript.
|
||||
`super` by itself a syntax error; whereas `super.foo` and `super["foo"]` are valid expressions.
|
||||
|
||||
[[module-keyword]]
|
||||
=== `module` keyword
|
||||
|
||||
The `module` keyword can be used as either a value, or as a type.
|
||||
|
||||
When used as a value, it refers to the <<receiver,receiver>> of the module itself.
|
||||
|
||||
[source%tested,pkl]
|
||||
----
|
||||
name = "Quail"
|
||||
|
||||
some {
|
||||
deep {
|
||||
object {
|
||||
name = module.name // <1>
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> Resolves to `"Quail"`
|
||||
|
||||
When used as a type, it is the module's class.
|
||||
|
||||
[source%parsed,pkl]
|
||||
----
|
||||
module Bird
|
||||
|
||||
friend: module // <1>
|
||||
----
|
||||
<1> Is class `Bird`
|
||||
|
||||
The `module` type is a _self type_.
|
||||
If the module is extended by another module, the `module` type refers to the extending module when
|
||||
in the context of that module.
|
||||
|
||||
[[glob-patterns]]
|
||||
=== Glob Patterns
|
||||
|
||||
@@ -4706,8 +5120,8 @@ TIP: If incorporating escape characters into a glob pattern, use <<custom-string
|
||||
|===
|
||||
|Pattern |Description
|
||||
|
||||
|`*.pc[lf]`
|
||||
|Anything suffixed by `.pkl`, or `.pcf`.
|
||||
|`*.pk[lg]`
|
||||
|Anything suffixed by `.pkl`, or `.pkg`.
|
||||
|
||||
|`**.y{a,}ml`
|
||||
|Anything suffixed by either `yml` or `yaml`, crossing directory boundaries.
|
||||
@@ -5065,11 +5479,6 @@ For example, the prototype chain of value `42` contains, now listed from top to
|
||||
|
||||
A prototype chain never contains a non-object value, such as `42`.
|
||||
|
||||
[[grammar-definition]]
|
||||
=== Grammar Definition
|
||||
|
||||
Pkl's link:{uri-antlr4}[ANTLR 4] grammar is defined in link:{uri-github-PklLexer}[PklLexer.g4] and link:{uri-github-PklParser}[PklParser.g4].
|
||||
|
||||
[[reserved-keywords]]
|
||||
=== Reserved keywords
|
||||
|
||||
@@ -5086,6 +5495,8 @@ They cannot be used as a regular identifier, and currently do not have any meani
|
||||
|
||||
To use these names in an identifier, <<quoted-identifiers, surround them with backticks>>.
|
||||
|
||||
For a complete list of keywords, consult field `Lexer.KEYWORDS` in {uri-github-PklLexer}[Lexer.java].
|
||||
|
||||
[[blank-identifiers]]
|
||||
=== Blank Identifiers
|
||||
|
||||
@@ -5146,8 +5557,8 @@ It is defined by the presence of a `PklProject` file that amends the standard li
|
||||
Defining a project serves the following purposes:
|
||||
|
||||
1. It allows defining common evaluator settings for Pkl modules within a logical project.
|
||||
2. It helps with managing <<packages,package>> dependencies for Pkl modules within a logical project.
|
||||
3. It enables packaging and sharing the contents of the project as a <<packages,package>>.
|
||||
2. It helps with managing <<package-asset-uri,package>> dependencies for Pkl modules within a logical project.
|
||||
3. It enables packaging and sharing the contents of the project as a <<package-asset-uri,package>>.
|
||||
4. It allows importing packages via dependency notation.
|
||||
|
||||
[[project-dependencies]]
|
||||
@@ -5225,7 +5636,7 @@ package {
|
||||
packageZipUrl = "https://example.com/\(name)/\(name)@\(version).zip" // <4>
|
||||
}
|
||||
----
|
||||
<1> The display name of the package. For display purposes only.
|
||||
<1> The display name of the package.For display purposes only.
|
||||
<2> The package URI, without the version part.
|
||||
<3> The version of the package.
|
||||
<4> The URL to download the package's ZIP file.
|
||||
@@ -5233,8 +5644,9 @@ package {
|
||||
The package itself is created by the command xref:pkl-cli:index.adoc#command-project-package[`pkl project package`].
|
||||
|
||||
This command only prepares artifacts to be published.
|
||||
Once the artifacts are prepared, they are expected to be uploaded to an HTTPS server such that the ZIP asset can be downloaded at path `packageZipUrl`, and the metadata can be downloaded at `+https://<package uri>+`.
|
||||
Once the artifacts are prepared, they are expected to be uploaded to an HTTPS server such that the ZIP asset can be downloaded at path `packageZipUrl`, and the metadata can be downloaded at `+https://<package uri>+`.
|
||||
|
||||
[[local-dependencies]]
|
||||
==== Local dependencies
|
||||
|
||||
A project can depend on a local project as a dependency.
|
||||
@@ -5282,3 +5694,90 @@ It can be imported using dependency notation, i.e. `import "@fruit/Pear.pkl"`.
|
||||
At runtime, it will resolve to relative path `../fruit/Pear.pkl`.
|
||||
|
||||
When packaging projects with local dependencies, both the project and its dependent project must be passed to the xref:pkl-cli:index.adoc#command-project-package[`pkl project package`] command.
|
||||
|
||||
[[external-readers]]
|
||||
=== External Readers
|
||||
|
||||
External readers are a mechanism to extend the <<modules,module>> and <<resources,resource>> URI schemes that Pkl supports.
|
||||
Readers are implemented as ordinary executables and use Pkl's xref:bindings-specification:message-passing-api.adoc[message passing API] to communicate with the hosting Pkl evaluator.
|
||||
The xref:swift:ROOT:index.adoc[Swift] and xref:go:ROOT:index.adoc[Go] language binding libraries provide an `ExternalReaderRuntime` type to facilitate implementing external readers.
|
||||
|
||||
External readers are configured separately for modules and resources.
|
||||
They are registered by mapping their URI scheme to the executable to run and additional arguments to pass.
|
||||
This is done on the command line by passing `--external-resource-reader` and `--external-module-reader` flags, which may both be passed multiple times.
|
||||
|
||||
[source,text]
|
||||
----
|
||||
$ pkl eval <module> --external-resource-reader <scheme>=<executable> --external-module-reader <scheme>='<executable> <argument> <argument>'
|
||||
----
|
||||
|
||||
External readers may also be configured in a <<projects, Project's>> `PklProject` file.
|
||||
[source,{pkl}]
|
||||
----
|
||||
evaluatorSettings {
|
||||
externalResourceReaders {
|
||||
["<scheme>"] {
|
||||
executable = "<executable>"
|
||||
}
|
||||
}
|
||||
externalModuleReaders {
|
||||
["<scheme>"] {
|
||||
executable = "<executable>"
|
||||
arguments { "<arg>"; "<arg>" }
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Registering an external reader for a scheme automatically adds that scheme to the default allowed modules/resources.
|
||||
As with Pkl's built-in module and resource schemes, setting explicit allowed modules or resources overrides this behavior and appropriate patterns must be specified to allow use of external readers.
|
||||
|
||||
==== Example
|
||||
|
||||
Consider this module:
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
username = "pigeon"
|
||||
|
||||
email = read("ldap://ds.example.com:389/dc=example,dc=com?mail?sub?(uid=\(username))").text
|
||||
----
|
||||
|
||||
Pkl doesn't implement the `ldap:` resource URI scheme natively, but an external reader can provide it.
|
||||
Assuming a hypothetical `pkl-ldap` executable implementing the external reader protocol and the `ldap:` scheme is in the `$PATH`, this module can be evaluated as:
|
||||
|
||||
[source,text]
|
||||
----
|
||||
$ pkl eval <module> --external-resource-reader ldap=pkl-ldap
|
||||
username = "pigeon"
|
||||
email = "pigeon@example.com"
|
||||
----
|
||||
|
||||
In this example, the external reader may provide both `ldap:` and `ldaps:` schemes.
|
||||
To support both schemes during evaluation, both would need to be registered explicitly:
|
||||
[source,text]
|
||||
----
|
||||
$ pkl eval <module> --external-resource-reader ldap=pkl-ldap --external-resource-reader ldaps=pkl-ldap
|
||||
----
|
||||
|
||||
[[mirroring_packages]]
|
||||
=== Mirroring packages
|
||||
|
||||
A package is a shareable archive of modules and resources that are published to the internet.
|
||||
|
||||
A package's URI tells two things:
|
||||
|
||||
1. The name of the package.
|
||||
2. Where the package is downloaded from.
|
||||
|
||||
For example, given the package name `package://example.com/mypackage@1.0.0`, Pkl will make an HTTPS request to `\https://example.com/mypackage@1.0.0` to fetch package metadata.
|
||||
|
||||
In situations where internet access is restricted, a mirror can be set up to allow use of packages that are published to the internet.
|
||||
|
||||
To direct Pkl to a mirror, the `--http-rewrite` CLI option (and its equivalent options when using Pkl's other evaluator APIs) must be used.
|
||||
For example, `--http-rewrite \https://pkg.pkl-lang.org/=\https://my.internal.mirror/` will tell Pkl to download packages from host `my.internal.mirror`.
|
||||
|
||||
NOTE: To effectively mirror packages from pkg.pkl-lang.org, there must be two rewrites; one for `\https://pkg.pkl-lang.org/` (where package metadata is downloaded), and one for `\https://github.com/` (where package zip files are downloaded).
|
||||
|
||||
NOTE: Pkl does not provide any tooling to run a mirror server.
|
||||
To fully set up mirroring, an HTTP(s) server will need be running, and which mirrors the same assets byte-for-byte.
|
||||
|
||||
@@ -134,6 +134,7 @@ exampleObjectWithMixedElements {
|
||||
<2> Elements don't have to be literal values; they can be arbitrary _expressions_.
|
||||
<3> Elements can really be _any_ value, not just primitive values.
|
||||
|
||||
[[entries]]
|
||||
=== Entries
|
||||
|
||||
Objects can have one more kind of member; _entries_.
|
||||
|
||||
@@ -213,7 +213,7 @@ adultBirdFoods {
|
||||
|
||||
A `.pkl` file describes a _module_.
|
||||
Modules are objects that can be referred to from other modules.
|
||||
Going back to the example above, you can write `parrot` as a separate module.
|
||||
Going back to the example above, you can write `pigeon` as a separate module.
|
||||
|
||||
[source,{pkl}]
|
||||
.pigeon.pkl
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
= CLI
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-homebrew: https://brew.sh
|
||||
:uri-mise: https://mise.jdx.dev
|
||||
:uri-winget: https://learn.microsoft.com/en-us/windows/package-manager/
|
||||
|
||||
:uri-sonatype-snapshot-download: https://s01.oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=org.pkl-lang&v={pkl-artifact-version}
|
||||
:uri-pkl-macos-amd64-download: {uri-sonatype-snapshot-download}&a=pkl-cli-macos-amd64&e=bin
|
||||
:uri-pkl-macos-aarch64-download: {uri-sonatype-snapshot-download}&a=pkl-cli-macos-aarch64&e=bin
|
||||
:uri-pkl-linux-amd64-download: {uri-sonatype-snapshot-download}&a=pkl-cli-linux-amd64&e=bin
|
||||
@@ -53,8 +54,7 @@ whereas, the Alpine Linux executable is statically linked against _musl libc_ an
|
||||
====
|
||||
|
||||
The Java executable works on multiple platforms and has a smaller binary size than the native executables.
|
||||
However, it requires a Java 17 (or higher) runtime on the system path, has a noticeable startup delay,
|
||||
and runs complex Pkl code slower than the native executables.
|
||||
However, it requires a Java 17 (or higher) runtime on the system path, and has a noticeable startup delay.
|
||||
|
||||
All flavors are built from the same codebase and undergo the same automated testing.
|
||||
Except where noted otherwise, the rest of this page discusses the native executables.
|
||||
@@ -85,6 +85,54 @@ ifndef::is-release-version[]
|
||||
For instructions, switch to a release version of this page.
|
||||
endif::[]
|
||||
|
||||
[[mise]]
|
||||
=== Mise
|
||||
|
||||
On macOS, Linux, and Windows, release versions can be installed with {uri-mise}[Mise].
|
||||
|
||||
ifdef::is-release-version[]
|
||||
To install Pkl, run:
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
# Install and activate Pkl globally
|
||||
mise use -g pkl@{pkl-version}
|
||||
|
||||
# Install and activate Pkl locally
|
||||
mise use pkl@{pkl-version}
|
||||
----
|
||||
endif::[]
|
||||
|
||||
ifndef::is-release-version[]
|
||||
For instructions, switch to a release version of this page.
|
||||
endif::[]
|
||||
|
||||
[[winget]]
|
||||
=== Windows Package Manager
|
||||
|
||||
On Windows, release versions can be installed with {uri-winget}[Windows Package Manager].
|
||||
|
||||
ifdef::is-release-version[]
|
||||
To install Pkl, run:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
winget install Apple.Pkl
|
||||
----
|
||||
|
||||
To update Pkl, run:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
winget upgrade Apple.Pkl
|
||||
----
|
||||
endif::[]
|
||||
|
||||
ifndef::is-release-version[]
|
||||
For instructions, switch to a release version of this page.
|
||||
endif::[]
|
||||
|
||||
[[download]]
|
||||
=== Download
|
||||
|
||||
@@ -201,6 +249,14 @@ NOTE: We currently do not support the aarch64 architecture for Windows.
|
||||
[[java-executable]]
|
||||
=== Java Executable
|
||||
|
||||
The Java executable is a jar that can be executed directly on macOS, Linux, and Windows.
|
||||
|
||||
It requires `java` to be installed, and available on `$PATH`.
|
||||
|
||||
[tabs]
|
||||
====
|
||||
macOS/Linux::
|
||||
+
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
@@ -209,6 +265,16 @@ chmod +x jpkl
|
||||
./jpkl --version
|
||||
----
|
||||
|
||||
Windows::
|
||||
+
|
||||
[source,PowerShell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
Invoke-WebRequest '{uri-pkl-java-download}' -OutFile jpkl.bat
|
||||
.\jpkl --version
|
||||
----
|
||||
====
|
||||
|
||||
This should print something similar to:
|
||||
|
||||
[source,shell]
|
||||
@@ -217,8 +283,7 @@ This should print something similar to:
|
||||
Pkl {pkl-version} (macOS 14.2, Java 17.0.10)
|
||||
----
|
||||
|
||||
NOTE: The Java executable does not work as an executable file on Windows.
|
||||
However, it will work as a jar, for example, with `java -jar jpkl`.
|
||||
NOTE: The Java executable is named `jpkl`.
|
||||
|
||||
[[usage]]
|
||||
== Usage
|
||||
@@ -342,7 +407,7 @@ pkl eval -m . myFiles.pkl
|
||||
pkl eval -m "%{moduleName}" foo.pkl bar.pkl
|
||||
----
|
||||
|
||||
For additional details, see xref:language-reference:index.adoc#multiple-file-output[Multiple File Output]
|
||||
For additional details, see xref:language-reference:index.adoc#multiple-file-output[Multiple File Output]
|
||||
in the language reference.
|
||||
====
|
||||
|
||||
@@ -409,6 +474,10 @@ Evaluate the given `<modules>` as _tests_, producing a test report and appropria
|
||||
|
||||
Renderers defined in test files will be ignored by the `test` command.
|
||||
|
||||
Tests that result in writing `pkl-expected.pcf` files are considered failing tests.
|
||||
If these are the only failures, the command exits with exit code 10.
|
||||
Otherwise, failures result in exit code 1.
|
||||
|
||||
<modules>::
|
||||
The absolute or relative URIs of the modules to test. Relative URIs are resolved against the working directory.
|
||||
|
||||
@@ -422,9 +491,31 @@ Default: (none) +
|
||||
Example: `./build/test-results` +
|
||||
Directory where to store JUnit reports.
|
||||
|
||||
By default, one file will be created for each test module. This behavior can be changed with `--junit-aggregate-reports`, which will instead create a single JUnit report file with all test results.
|
||||
|
||||
No JUnit reports will be generated if this option is not present.
|
||||
====
|
||||
|
||||
[[junit-aggregate-reports]]
|
||||
.--junit-aggregate-reports
|
||||
[%collapsible]
|
||||
====
|
||||
Aggregate JUnit reports into a single file.
|
||||
|
||||
By default it will be `pkl-tests.xml` but you can override it using `--junit-aggregate-suite-name` flag.
|
||||
====
|
||||
|
||||
[[junit-aggregate-suite-name]]
|
||||
.--junit-aggregate-suite-name
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: `my-tests` +
|
||||
The name of the root JUnit test suite.
|
||||
|
||||
Used in combination with `--junit-aggregate-reports` flag.
|
||||
====
|
||||
|
||||
[[overwrite]]
|
||||
.--overwrite
|
||||
[%collapsible]
|
||||
@@ -512,6 +603,24 @@ Directory where to store JUnit reports.
|
||||
No JUnit reports will be generated if this option is not present.
|
||||
====
|
||||
|
||||
.--junit-aggregate-reports
|
||||
[%collapsible]
|
||||
====
|
||||
Aggregate JUnit reports into a single file.
|
||||
|
||||
By default it will be `pkl-tests.xml` but you can override it using `--junit-aggregate-suite-name` flag.
|
||||
====
|
||||
|
||||
.--junit-aggregate-suite-name
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: `my-tests` +
|
||||
The name of the root JUnit test suite.
|
||||
|
||||
Used in combination with `--junit-aggregate-reports` flag.
|
||||
====
|
||||
|
||||
.--overwrite
|
||||
[%collapsible]
|
||||
====
|
||||
@@ -558,14 +667,80 @@ package already exists in the cache directory, this command is a no-op.
|
||||
|
||||
This command accepts <<common-options,common options>>.
|
||||
|
||||
[[command-analyze-imports]]
|
||||
=== `pkl analyze imports`
|
||||
|
||||
*Synopsis*: `pkl analyze imports [<modules>]`
|
||||
|
||||
This command builds a graph of imports declared in the provided modules.
|
||||
|
||||
This is a lower level command that is meant to be useful for Pkl-related tooling.
|
||||
For example, this command feeds into the xref:pkl-gradle:index.adoc[] to determine if tasks are considered up-to-date or not.
|
||||
|
||||
This command produces an object with two properties, `imports` and `resolvedImports`.
|
||||
|
||||
The `imports` property is a mapping of a module's absolute URI, to the set of imports declared within that module.
|
||||
|
||||
The `resolvedImports` property is a mapping of a module's absolute URI (as stated in `imports`), to the resolved absolute URI that might be useful for fetching the module's contents.
|
||||
For example, a xref:language-reference:index.adoc#local-dependencies[local dependency] import will have an in-language URI with scheme `projectpackage:`, and may have resolved URI with scheme `file:` (assuming that the project is file-based).
|
||||
|
||||
Examples:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
# Analyze the imports of a single module
|
||||
pkl analyze imports myModule.pkl
|
||||
|
||||
# Same as the previous command, but output in JSON.
|
||||
pkl analyze imports -f json myModule.pkl
|
||||
|
||||
# Analyze imports of all modules declared within src/
|
||||
pkl analyze imports src/*.pkl
|
||||
----
|
||||
|
||||
<modules>::
|
||||
The absolute or relative URIs of the modules to analyze. Relative URIs are resolved against the working directory.
|
||||
|
||||
==== Options
|
||||
|
||||
.-f, --format
|
||||
[%collapsible]
|
||||
====
|
||||
Same meaning as <<format>> in <<command-eval>>.
|
||||
====
|
||||
|
||||
.-o, --output-path
|
||||
[%collapsible]
|
||||
====
|
||||
Same meaning as <<output-path>> in <<command-eval>>.
|
||||
====
|
||||
|
||||
This command also takes <<common-options,common options>>.
|
||||
|
||||
[[command-shell-completion]]
|
||||
=== `pkl shell-completion`
|
||||
|
||||
*Synopsis*: `pkl shell-completion <shell>`
|
||||
|
||||
Generate shell completion script. Supported shells are: `bash`, `zsh`, `fish`.
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
# Generate shell completion script for bash
|
||||
pkl shell-completion bash
|
||||
|
||||
# Generate shell completion script for zsh
|
||||
pkl shell-completion zsh
|
||||
----
|
||||
|
||||
[[common-options]]
|
||||
=== Common options
|
||||
|
||||
The <<command-eval>>, <<command-test>>, <<command-repl>>, <<command-project-resolve>>, <<command-project-package>>, and <<command-download-package>> commands support the following common options:
|
||||
The <<command-eval>>, <<command-test>>, <<command-repl>>, <<command-project-resolve>>, <<command-project-package>>, <<command-download-package>>, and <<command-analyze-imports>> commands support the following common options:
|
||||
|
||||
include::../../pkl-cli/partials/cli-common-options.adoc[]
|
||||
|
||||
The <<command-eval>>, <<command-test>>, <<command-repl>>, and <<command-download-package>> commands also take the following options:
|
||||
The <<command-eval>>, <<command-test>>, <<command-repl>>, <<command-download-package>>, and <<command-analyze-imports>> commands also take the following options:
|
||||
|
||||
include::../../pkl-cli/partials/cli-project-options.adoc[]
|
||||
|
||||
@@ -667,8 +842,6 @@ Type :help or :examples for more information.
|
||||
pkl>
|
||||
----
|
||||
|
||||
NOTE: The Java executable is named `jpkl`.
|
||||
|
||||
=== Loading Modules
|
||||
|
||||
To load <<config.pkl,`config.pkl`>> into the REPL, run:
|
||||
|
||||
@@ -7,7 +7,6 @@ Comma-separated list of URI patterns that determine which modules can be loaded
|
||||
Patterns are matched against the beginning of module URIs.
|
||||
(File paths have been converted to `file:` URLs at this stage.)
|
||||
At least one pattern needs to match for a module to be loadable.
|
||||
Both source modules and transitive modules are subject to this check.
|
||||
====
|
||||
|
||||
[[allowed-resources]]
|
||||
@@ -20,6 +19,19 @@ Patterns are matched against the beginning of resource URIs.
|
||||
At least one pattern needs to match for a resource to be readable.
|
||||
====
|
||||
|
||||
[[color]]
|
||||
.--color
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `auto` +
|
||||
When to format messages with ANSI color codes.
|
||||
Possible values:
|
||||
|
||||
- `"never"`: Never format
|
||||
- `"auto"`: Format if `stdin`, `stdout`, or `stderr` are connected to a console.
|
||||
- `"always"`: Always format
|
||||
====
|
||||
|
||||
[[cache-dir]]
|
||||
.--cache-dir
|
||||
[%collapsible]
|
||||
@@ -140,3 +152,14 @@ Example: `example.com,169.254.0.0/16` +
|
||||
Comma separated list of hosts to which all connections should bypass the proxy.
|
||||
Hosts can be specified by name, IP address, or IP range using https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation[CIDR notation].
|
||||
====
|
||||
|
||||
.--http-rewrite
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: `\https://pkg.pkl-lang.org/=https://my.internal.mirror/` +
|
||||
Replace outbound HTTP(S) requests from one URL with another URL.
|
||||
The left-hand side describes the source prefix, and the right-hand describes the target prefix.
|
||||
This option is commonly used to enable package mirroring.
|
||||
The above example will rewrite URL `\https://pkg.pkl-lang.org/pkl-k8s/k8s@1.0.0` to `\https://my.internal.mirror/pkl-k8s/k8s@1.0.0`.
|
||||
====
|
||||
|
||||
@@ -6,7 +6,7 @@ import org.pkl.core.PModule;
|
||||
import org.pkl.core.PObject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
// the pkl/pkl-examples repo has a similar example
|
||||
// the pkl-jvm-examples repo has a similar example
|
||||
@SuppressWarnings({"unchecked", "unused", "ConstantConditions"})
|
||||
public class CoreEvaluatorExample {
|
||||
@Test
|
||||
|
||||
@@ -5,6 +5,23 @@ include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-DocPackageInfo: {uri-pkl-stdlib-docs}/DocPackageInfo/
|
||||
:uri-CliDocGenerator: {uri-pkl-doc-main-sources}/CliDocGenerator.kt
|
||||
:uri-DocGenerator: {uri-pkl-doc-main-sources}/DocGenerator.kt
|
||||
:uri-pkldoc-macos-amd64-download: {uri-sonatype-snapshot-download}&a=pkldoc-macos-amd64&e=bin
|
||||
:uri-pkldoc-macos-aarch64-download: {uri-sonatype-snapshot-download}&a=pkldoc-macos-aarch64&e=bin
|
||||
:uri-pkldoc-linux-amd64-download: {uri-sonatype-snapshot-download}&a=pkldoc-linux-amd64&e=bin
|
||||
:uri-pkldoc-linux-aarch64-download: {uri-sonatype-snapshot-download}&a=pkldoc-linux-aarch64&e=bin
|
||||
:uri-pkldoc-alpine-download: {uri-sonatype-snapshot-download}&a=pkldoc-alpine-linux-amd64&e=bin
|
||||
:uri-pkldoc-windows-download: {uri-sonatype-snapshot-download}&a=pkldoc-windows-amd64&e=exe
|
||||
:uri-pkldoc-java-download: {uri-sonatype-snapshot-download}&a=pkldoc-java&e=jar
|
||||
|
||||
ifdef::is-release-version[]
|
||||
:uri-pkldoc-macos-amd64-download: {github-releases}/pkldoc-macos-amd64
|
||||
:uri-pkldoc-macos-aarch64-download: {github-releases}/pkldoc-macos-aarch64
|
||||
:uri-pkldoc-linux-amd64-download: {github-releases}/pkldoc-linux-amd64
|
||||
:uri-pkldoc-linux-aarch64-download: {github-releases}/pkldoc-linux-aarch64
|
||||
:uri-pkldoc-alpine-download: {github-releases}/pkldoc-alpine-linux-amd64
|
||||
:uri-pkldoc-windows-download: {github-releases}/pkldoc-windows-amd64.exe
|
||||
:uri-pkldoc-java-download: {github-releases}/jpkldoc
|
||||
endif::[]
|
||||
|
||||
_Pkldoc_ is a documentation website generator that produces navigable and searchable API documentation for Pkl modules.
|
||||
|
||||
@@ -77,7 +94,7 @@ The `pkl-doc` library is available {uri-pkl-doc-maven}[from Maven Central].
|
||||
It requires Java 17 or higher.
|
||||
|
||||
ifndef::is-release-version[]
|
||||
NOTE: Snapshots are published to repository `{uri-sonatype}`.
|
||||
NOTE: Snapshots are published to repository `{uri-snapshot-repo}`.
|
||||
endif::[]
|
||||
|
||||
==== Gradle
|
||||
@@ -153,8 +170,33 @@ endif::[]
|
||||
[[install-cli]]
|
||||
=== CLI
|
||||
|
||||
The CLI is bundled with the library and does not currently ship as a native executable or a self-contained Jar.
|
||||
We recommend to provision it with a Maven compatible build tool as shown in <<install-library,Library Installation>>.
|
||||
The CLI comes in multiple flavors:
|
||||
|
||||
* Native macOS executable for amd64 (tested on macOS 10.15)
|
||||
* Native Linux executable for amd64
|
||||
* Native Linux executable for aarch64
|
||||
* Native Alpine Linux executable for amd64 (cross-compiled and tested on Oracle Linux 8)
|
||||
* Native Windows executable for amd64 (tested on Windows Server 2022)
|
||||
* Java executable (tested with Java 17/21 on macOS and Oracle Linux)
|
||||
|
||||
.What is the Difference Between the Linux and Alpine Linux Executables?
|
||||
[NOTE]
|
||||
====
|
||||
The Linux executable is dynamically linked against _glibc_ and _libstdc{plus}{plus}_,
|
||||
whereas, the Alpine Linux executable is statically linked against _musl libc_ and _libstdc{plus}{plus}_.
|
||||
====
|
||||
|
||||
The Java executable works on multiple platforms and has a smaller binary size than the native executables.
|
||||
However, it requires a Java 17 (or higher) runtime on the system path, and has a noticeable startup delay.
|
||||
|
||||
Download links:
|
||||
|
||||
* macOS aarch64: {uri-pkldoc-macos-aarch64-download}
|
||||
* macOS amd64: {uri-pkldoc-macos-amd64-download}
|
||||
* Linux aarch64: {uri-pkldoc-linux-aarch64-download}
|
||||
* Linux amd64: {uri-pkldoc-linux-amd64-download}
|
||||
* Alpine Linux amd64: {uri-pkldoc-alpine-download}
|
||||
* Windows amd64: {uri-pkldoc-windows-download}
|
||||
|
||||
[[usage]]
|
||||
== Usage
|
||||
@@ -162,7 +204,7 @@ We recommend to provision it with a Maven compatible build tool as shown in <<in
|
||||
The Pkldoc tool is offered as Gradle plugin, Java library, and CLI.
|
||||
It can generate documentation either for modules directly, or generate documentation for _package uris_.
|
||||
|
||||
The tool requires an argument of a module named `_docsite-info.pkl`, that amends link:{uri-DocsiteInfo}[pkl.DocsiteInfo].
|
||||
The tool requires an argument of a module named _docsite-info.pkl_, that amends link:{uri-DocsiteInfo}[pkl.DocsiteInfo].
|
||||
|
||||
[discrete]
|
||||
==== Generating documentation for modules directly
|
||||
@@ -216,10 +258,7 @@ For more information, refer to the Javadoc documentation.
|
||||
|
||||
=== CLI
|
||||
|
||||
As mentioned in <<install-cli,CLI Installation>>, the CLI is bundled with the library.
|
||||
To run the CLI, execute the library Jar or its `org.pkl.doc.Main` class.
|
||||
|
||||
*Synopsis:* `java -cp <classpath> -jar pkl-doc.jar [<options>] <modules>`
|
||||
*Synopsis:* `pkldoc [<options>] <modules>`
|
||||
|
||||
`<modules>`::
|
||||
The absolute or relative URIs of docsite descriptors, package descriptors, and the modules for which to generate documentation.
|
||||
@@ -232,10 +271,18 @@ Relative URIs are resolved against the working directory.
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: `pkldoc`
|
||||
Example: `pkldoc` +
|
||||
The directory where generated documentation is placed.
|
||||
====
|
||||
|
||||
.--no-symlinks
|
||||
[%collapsible]
|
||||
====
|
||||
Create copies of files and directories instead of symbolic links.
|
||||
In particular, this affects how the "current" directories containing documentation content for the last generated version should be created.
|
||||
By default, a symbolic link is created pointing to the last generated version. If symlinks are disabled, a full copy of the last generated version is created.
|
||||
====
|
||||
|
||||
Common CLI options:
|
||||
|
||||
include::../../pkl-cli/partials/cli-common-options.adoc[]
|
||||
@@ -244,4 +291,4 @@ include::../../pkl-cli/partials/cli-common-options.adoc[]
|
||||
== Full Example
|
||||
|
||||
For a ready-to-go example with full source code and detailed walkthrough,
|
||||
see link:{uri-pkldoc-example}[pkldoc] in the _pkl/pkl-examples_ repository.
|
||||
see link:{uri-pkldoc-example}[pkldoc] in the _pkl-jvm-examples_ repository.
|
||||
|
||||
@@ -25,7 +25,7 @@ It requires Java 17 or higher and Gradle 8.1 or higher.
|
||||
Earlier Gradle versions are not supported.
|
||||
|
||||
ifndef::is-release-version[]
|
||||
NOTE: Snapshots are published to repository `{uri-sonatype}`.
|
||||
NOTE: Snapshots are published to repository `{uri-snapshot-repo}`.
|
||||
endif::[]
|
||||
|
||||
The plugin is applied as follows:
|
||||
@@ -102,7 +102,6 @@ pkl {
|
||||
evaluators {
|
||||
evalPkl {
|
||||
sourceModules.add(file("module1.pkl"))
|
||||
transitiveModules.from file("module2.pkl")
|
||||
outputFile = layout.buildDirectory.file("module1.yaml")
|
||||
outputFormat = "yaml"
|
||||
}
|
||||
@@ -118,7 +117,6 @@ pkl {
|
||||
evaluators {
|
||||
register("evalPkl") {
|
||||
sourceModules.add(file("module1.pkl"))
|
||||
transitiveModules.from(file("module2.pkl"))
|
||||
outputFile.set(layout.buildDirectory.file("module1.yaml"))
|
||||
outputFormat.set("yaml")
|
||||
}
|
||||
@@ -127,9 +125,6 @@ pkl {
|
||||
----
|
||||
====
|
||||
|
||||
To guarantee correct Gradle up-to-date behavior,
|
||||
`transitiveModules` needs to contain all module files transitively referenced by `sourceModules`.
|
||||
|
||||
For each declared evaluator, the Pkl plugin creates an equally named task.
|
||||
Hence the above evaluator can be run with:
|
||||
|
||||
@@ -139,7 +134,7 @@ $ ./gradlew evalPkl
|
||||
----
|
||||
|
||||
For a ready-to-go example with full source code,
|
||||
see link:{uri-build-eval-example}[codegen-java] in the _pkl/pkl-examples_ repository.
|
||||
see link:{uri-build-eval-example}[codegen-java] in the _pkl-jvm-examples_ repository.
|
||||
|
||||
=== Configuration Options
|
||||
|
||||
@@ -200,7 +195,7 @@ Example 1: `multipleFileOutputDir = layout.projectDirectory.dir("output")` +
|
||||
Example 2: `+multipleFileOutputDir = layout.projectDirectory.file("%{moduleDir}/output")+`
|
||||
The directory where a module's output files are placed.
|
||||
|
||||
Setting this option causes Pkl to evaluate a module's `output.files` property
|
||||
Setting this option causes Pkl to evaluate a module's `output.files` property
|
||||
and write the files specified therein.
|
||||
Within `output.files`, a key determines a file's path relative to `multipleFileOutputDir`,
|
||||
and a value determines the file's contents.
|
||||
@@ -212,7 +207,7 @@ This option cannot be used together with any of the following:
|
||||
|
||||
This option supports the same placeholders as xref:output-file[outputFile].
|
||||
|
||||
For additional details, see xref:language-reference:index.adoc#multiple-file-output[Multiple File Output]
|
||||
For additional details, see xref:language-reference:index.adoc#multiple-file-output[Multiple File Output]
|
||||
in the language reference.
|
||||
====
|
||||
|
||||
@@ -303,6 +298,22 @@ Example: `junitReportsDir = layout.buildDirectory.dir("reports")` +
|
||||
Whether and where to generate JUnit XML reports.
|
||||
====
|
||||
|
||||
[[junit-aggregate-reports]]
|
||||
.junitAggregateReports: Property<Boolean>
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `false` +
|
||||
Aggregate JUnit reports into a single file.
|
||||
====
|
||||
|
||||
[[junit-aggregate-suite-name]]
|
||||
.junitAggregateSuiteName: Property<String>
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `null` +
|
||||
The name of the root JUnit test suite.
|
||||
====
|
||||
|
||||
[[overwrite]]
|
||||
.overwrite: Property<Boolean>
|
||||
[%collapsible]
|
||||
@@ -366,7 +377,7 @@ $ ./gradlew genJava
|
||||
----
|
||||
|
||||
For a ready-to-go example with full source code,
|
||||
see link:{uri-codegen-java-example}[codegen-java] in the _pkl/pkl-examples_ repository.
|
||||
see link:{uri-codegen-java-example}[codegen-java] in the _pkl-jvm-examples_ repository.
|
||||
|
||||
=== Configuration Options
|
||||
|
||||
@@ -378,14 +389,26 @@ Example: `generateGetters = true` +
|
||||
Whether to generate private final fields and public getter methods rather than public final fields.
|
||||
====
|
||||
|
||||
// TODO: fixme (paramsAnnotation, nonNullAnnotation)
|
||||
.preferJavaxInjectAnnotation: Boolean
|
||||
.paramsAnnotation: Property<String>
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `false` +
|
||||
Example: `preferJavaxInjectAnnotation = true` +
|
||||
Whether to annotate constructor parameters with `@javax.inject.Named` instead of `@org.pkl.config.java.mapper.Named`.
|
||||
If `true`, the generated code will have a compile dependency on `javax.inject:javax.inject:1`.
|
||||
Default: `null` if `generateSpringBootConfig` is `true`, `"org.pkl.config.java.mapper.Named"` otherwise+
|
||||
Example: `paramsAnnotation = "org.project.MyAnnotation"` +
|
||||
Fully qualified name of the annotation type to use for annotating constructor parameters with their name. +
|
||||
The specified annotation type must have a `value` parameter of type `String` or the generated code may not compile.
|
||||
If set to `null`, constructor parameters are not annotated.
|
||||
Whether and how constructor parameters should be annotated depends on the library that instantiates the generated classes.
|
||||
For Spring Boot applications, and for users of `pkl-config-java` compiling the generated classes with `-parameters`, no annotation is required.
|
||||
|
||||
====
|
||||
.nonNullAnnotation: Property<String>
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `"org.pkl.config.java.mapper.NonNull"` +
|
||||
Example: `nonNullAnnotation = "org.project.MyAnnotation"` +
|
||||
Fully qualified name of the annotation type to use for annotating non-null types. +
|
||||
The specified annotation type must be annotated with `@java.lang.annotation.Target(ElementType.TYPE_USE)`
|
||||
or the generated code may not compile.
|
||||
====
|
||||
|
||||
Common code generation properties:
|
||||
@@ -424,7 +447,7 @@ build.gradle.kts::
|
||||
+
|
||||
[source,kotlin]
|
||||
----
|
||||
pkl {
|
||||
pkl {
|
||||
kotlinCodeGenerators {
|
||||
register("genKotlin") {
|
||||
sourceModules.addAll(files("Template1.pkl", "Template2.pkl"))
|
||||
@@ -444,12 +467,19 @@ $ ./gradlew genKotlin
|
||||
----
|
||||
|
||||
For a ready-to-go example with full source code,
|
||||
see link:{uri-codegen-kotlin-example}[codegen-kotlin] in the _pkl/pkl-examples_ repository.
|
||||
see link:{uri-codegen-kotlin-example}[codegen-kotlin] in the _pkl-jvm-examples_ repository.
|
||||
|
||||
=== Configuration Options
|
||||
|
||||
// TODO: fixme (generateKdoc)
|
||||
(None)
|
||||
=== Configuration Options
|
||||
|
||||
.generateKdoc: Property<Boolean>
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `false` +
|
||||
Example: `generateKdoc = true` +
|
||||
Whether to preserve Pkl doc comments by generating corresponding KDoc comments.
|
||||
====
|
||||
|
||||
Common code generation properties:
|
||||
|
||||
@@ -506,7 +536,7 @@ $ ./gradlew pkldoc
|
||||
----
|
||||
|
||||
For a ready-to-go example with full source code,
|
||||
see link:{uri-pkldoc-example}[pkldoc] in the _pkl/pkl-examples_ repository.
|
||||
see link:{uri-pkldoc-example}[pkldoc] in the _pkl-jvm-examples_ repository.
|
||||
|
||||
=== Configuration Options
|
||||
|
||||
@@ -520,6 +550,17 @@ Example: `outputDir = layout.projectDirectory.dir("pkl-docs")` +
|
||||
The directory where generated documentation is placed.
|
||||
====
|
||||
|
||||
.noSymlinks: Property<Boolean>
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `false` +
|
||||
Example: `noSymlinks = true` +
|
||||
Create copies of files and directories instead of symbolic links.
|
||||
In particular, this affects how the "current" directories containing documentation content for the last generated version should be created.
|
||||
By default, a symbolic link is created pointing to the last generated version.
|
||||
If symlinks are disabled, a full copy of the last generated version is created.
|
||||
====
|
||||
|
||||
Common properties:
|
||||
|
||||
include::../partials/gradle-modules-properties.adoc[]
|
||||
@@ -691,3 +732,61 @@ The project directories to create packages for.
|
||||
Common properties:
|
||||
|
||||
include::../partials/gradle-common-properties.adoc[]
|
||||
|
||||
[[analyze-imports]]
|
||||
== Analyze Imports
|
||||
|
||||
This feature is the Gradle analogy for the xref:pkl-cli:index.adoc#command-analyze-imports[analyze imports] command in the CLI. It builds a graph of imports of the provided source modules.
|
||||
|
||||
=== Usage
|
||||
|
||||
[tabs]
|
||||
====
|
||||
build.gradle::
|
||||
+
|
||||
[source,groovy]
|
||||
----
|
||||
pkl {
|
||||
analyzers {
|
||||
imports {
|
||||
appConfig {
|
||||
sourceModules.add(file("src/main/resources/appConfig.pkl"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
build.gradle.kts::
|
||||
+
|
||||
[source,kotlin]
|
||||
----
|
||||
pkl {
|
||||
analyzers {
|
||||
imports {
|
||||
register("appConfig") {
|
||||
sourceModules.add(file("src/main/resources/appConfig.pkl"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
=== Configuration Options
|
||||
|
||||
.outputFormat: Property<String>
|
||||
[%collapsible]
|
||||
====
|
||||
Same meaning as <<output-format,outputFormat>> in <<module-evaluation>>.
|
||||
====
|
||||
|
||||
.outputFile: RegularFileProperty<String>
|
||||
[%collapsible]
|
||||
====
|
||||
Same meaning as <<output-file,outputFile>> in <<module-evaluation>>.
|
||||
====
|
||||
|
||||
Common properties:
|
||||
|
||||
include::../partials/gradle-modules-properties.adoc[]
|
||||
|
||||
@@ -36,6 +36,22 @@ Example: `generateSpringBootConfig = true` +
|
||||
Whether to generate config classes for use with Spring Boot.
|
||||
====
|
||||
|
||||
.implementSerializable: Property<Boolean>
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `false` +
|
||||
Example: `implementSerializable = true` +
|
||||
Whether to generate classes that implement `java.io.Serializable`.
|
||||
====
|
||||
|
||||
.addGeneratedAnnotation: Property<Boolean>
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `false` +
|
||||
Example: `addGeneratedAnnotation = true` +
|
||||
Whether to add the `org.pkl.config.java.Generated` annotation to generated types.
|
||||
====
|
||||
|
||||
.renames: MapProperty<String, String>
|
||||
[%collapsible]
|
||||
====
|
||||
@@ -86,4 +102,3 @@ Keys in this mapping can be arbitrary strings, including an empty string.
|
||||
Values must be valid dot-separated fully qualifed class name prefixes, possibly terminated by a dot.
|
||||
====
|
||||
|
||||
// TODO: fixme (implementSerializable)
|
||||
|
||||
@@ -7,7 +7,6 @@ URI patterns that determine which modules can be loaded and evaluated.
|
||||
Patterns are matched against the beginning of module URIs.
|
||||
(File paths have been converted to `file:` URLs at this stage.)
|
||||
At least one pattern needs to match for a module to be loadable.
|
||||
Both source modules and transitive modules are subject to this check.
|
||||
====
|
||||
|
||||
.allowedResources: ListProperty<String>
|
||||
@@ -68,6 +67,13 @@ The cache directory for storing packages.
|
||||
If `null`, defaults to `~/.pkl/cache`.
|
||||
====
|
||||
|
||||
.color: Property<Boolean>
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `false` +
|
||||
Format messages using ANSI color.
|
||||
====
|
||||
|
||||
.noCache: Property<Boolean>
|
||||
[%collapsible]
|
||||
====
|
||||
@@ -101,3 +107,14 @@ Example: `noProxy = ["example.com", "169.254.0.0/16"]` +
|
||||
Hosts to which all connections should bypass the proxy.
|
||||
Hosts can be specified by name, IP address, or IP range using https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation[CIDR notation].
|
||||
====
|
||||
|
||||
.httpRewrites: MapProperty<String, String>
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `null` +
|
||||
Example: `httpRewrites = [uri("https://pkg.pkl-lang.org/"): uri("https://my.internal.mirror/")]` +
|
||||
Replace outbound HTTP(S) requests from one URL with another URL.
|
||||
The left-hand side describes the source prefix, and the right-hand describes the target prefix.
|
||||
This option is commonly used to enable package mirroring.
|
||||
The above example will rewrite URL `\https://pkg.pkl-lang.org/pkl-k8s/k8s@1.0.0` to `\https://my.internal.mirror/pkl-k8s/k8s@1.0.0`.
|
||||
====
|
||||
|
||||
@@ -20,11 +20,17 @@ This property accepts the following types to represent a module:
|
||||
.transitiveModules: ConfigurableFileCollection
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `files()` (empty collection) +
|
||||
Default: [computed by pkl-gradle] +
|
||||
Example 1: `transitiveModules.from files("module1.pkl", "module2.pkl")` +
|
||||
Example 2: `+transitiveModules.from fileTree("config").include("**/*.pkl")+` +
|
||||
|
||||
File paths of modules that are directly or indirectly used by source modules.
|
||||
Setting this option enables correct Gradle up-to-date checks, which ensures that your Pkl tasks are executed if any of the transitive files are modified; it does not affect evaluation otherwise.
|
||||
|
||||
This property, along with `sourceModules`, is the set of input files used to determine whether this task is up-to-date or not.
|
||||
|
||||
By default, Pkl computes this property by analyzing the imports of the source modules.
|
||||
Setting this property explicitly causes Pkl to skip the analyze imports step.
|
||||
|
||||
Including source modules in `transitiveModules` is permitted but not required.
|
||||
Relative paths are resolved against the project directory.
|
||||
====
|
||||
|
||||
BIN
docs/modules/release-notes/images/error_sample.png
Normal file
BIN
docs/modules/release-notes/images/error_sample.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
BIN
docs/modules/release-notes/images/pkl-cli-help-new.png
Normal file
BIN
docs/modules/release-notes/images/pkl-cli-help-new.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 119 KiB |
BIN
docs/modules/release-notes/images/test_sample.png
Normal file
BIN
docs/modules/release-notes/images/test_sample.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
@@ -1,6 +1,6 @@
|
||||
= Pkl 0.26 Release Notes
|
||||
:version: 0.26
|
||||
:version-minor: 0.26.0
|
||||
:version-minor: 0.26.3
|
||||
:release-date: June 17th, 2024
|
||||
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
@@ -12,7 +12,7 @@ This release brings Windows support, improvements to controlling how Pkl talks o
|
||||
|
||||
The next release (0.27) is scheduled for October 10th, 2024.
|
||||
|
||||
Please send feedback and questions to https://github.com/apple/pkl/discussions[GitHub Discussions], or submit an issue on https://github.com/apple/pkl/issues/new[Github]. +
|
||||
Please send feedback and questions to https://github.com/apple/pkl/discussions[GitHub Discussions], or submit an issue on https://github.com/apple/pkl/issues/new[GitHub]. +
|
||||
|
||||
[small]#Pkl is hosted on https://github.com/apple/pkl[GitHub].
|
||||
To get started, follow xref:pkl-cli:index.adoc#installation[Installation].#
|
||||
@@ -460,7 +460,7 @@ To mitigate, the package's version needs to be bumped, even if package contents
|
||||
|
||||
== Miscellaneous [small]#🐸#
|
||||
|
||||
The following changes have been made that are not new features, nor breaking changes.
|
||||
The following changes have been made that are neither new features nor breaking changes.
|
||||
|
||||
* Pkl's user-agent header for HTTP requests has been tweaked to add a semicolon (https://github.com/apple/pkl/pull/221[#221]). Here is an example difference:
|
||||
+
|
||||
@@ -508,6 +508,7 @@ We would like to thank the contributors to this release (in alphabetical order):
|
||||
* https://github.com/MarkSRobinson[@MarkSRobinson]
|
||||
* https://github.com/mitchcapper[@mitchcapper]
|
||||
* https://github.com/mrs1669[@mrs1669]
|
||||
* https://github.com/netvl[@netvl]
|
||||
* https://github.com/nirinchev[@nirinchev]
|
||||
* https://github.com/raj-j-shah[@raj-j-shah]
|
||||
* https://github.com/sgammon[@sgammon]
|
||||
|
||||
542
docs/modules/release-notes/pages/0.27.adoc
Normal file
542
docs/modules/release-notes/pages/0.27.adoc
Normal file
@@ -0,0 +1,542 @@
|
||||
= Pkl 0.27 Release Notes
|
||||
:version: 0.27
|
||||
:version-minor: 0.27.2
|
||||
:release-date: November 5th, 2024
|
||||
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
|
||||
Pkl {version} was released on {release-date}. +
|
||||
[.small]#The latest bugfix release is {version-minor}. (xref:changelog.adoc[All Versions])#
|
||||
|
||||
This release brings improvements in typechecking of `Listing` and `Mapping`, the ability to use readers from external processes, as well as a new import graph analyzer API.
|
||||
|
||||
The next release (0.28) is scheduled for February 2025.
|
||||
|
||||
Please send feedback and questions to https://github.com/apple/pkl/discussions[GitHub Discussions], or submit an issue on https://github.com/apple/pkl/issues/new[GitHub]. +
|
||||
|
||||
[small]#Pkl is hosted on https://github.com/apple/pkl[GitHub].
|
||||
To get started, follow xref:pkl-cli:index.adoc#installation[Installation].#
|
||||
|
||||
== Highlights [small]#💖#
|
||||
|
||||
News you don't want to miss.
|
||||
|
||||
[#typecheck-improvements]
|
||||
=== Improved typechecking of `Listing` and `Mapping` types
|
||||
|
||||
Typechecking of `Listing` and `Mapping` types has been improved (https://github.com/apple/pkl/pull/628[#628], https://github.com/apple/pkl/pull/725[#725], https://github.com/apple/pkl/pull/740[#740], https://github.com/apple/pkl/pull/752[#752], https://github.com/apple/pkl/pull/778[#778], https://github.com/apple/pkl/pull/781[#781]).
|
||||
|
||||
Today, the typecheck `listing: Listing<E>` immediately evaluates all listing elements to check that they have type `E`.
|
||||
Likewise, the typecheck `mapping: Mapping<K, V>` immediately evaluates all mapping values to check that they have type `V`.
|
||||
|
||||
For example, the typecheck `listing: Listing<Bird>` proceeds as follows:
|
||||
|
||||
1. Check that `listing` has type `Listing`
|
||||
2. Evaluate each listing element and check that it has type `Bird`
|
||||
|
||||
This behavior is different from how the rest of Pkl works.
|
||||
Generally, Pkl only evaluates code that affects program output.
|
||||
|
||||
For example, consider the following program:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
class Bird {
|
||||
name: String
|
||||
canFly: Boolean
|
||||
}
|
||||
|
||||
local bird: Bird = new {
|
||||
name = "Pidgy"
|
||||
canFly = throw("uh oh")
|
||||
}
|
||||
|
||||
birdName = bird.name
|
||||
----
|
||||
|
||||
Even though `bird.canFly` throws an error, the above program succeeds because `bird.canFly` is not part of the program's output and hence is never accessed (Note that `bird` is a _local_ property).
|
||||
|
||||
Typechecks of `Mapping` and `Listing` types have been changed to match this behavior.
|
||||
Mapping and listing values are now only typechecked if and when they are accessed.
|
||||
|
||||
NOTE: Mapping _keys_ are still eagerly checked.
|
||||
|
||||
This change causes some previously failing programs to evaluate successfully:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
local myNumbers: Listing<Int> = new { 1; 2; "uh oh" }
|
||||
result = myNumbers[0]
|
||||
----
|
||||
In Pkl 0.26 and below, the above program fails with a type mismatch error because element `"uh oh"` is typechecked when `myNumbers` is accessed.
|
||||
In Pkl 0.27, the same program succeeds, because only element `myNumbers[0]` is part of the program's output and its typecheck succeeds.
|
||||
|
||||
As another consequence of this change, some Pkl programs now complete more quickly:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
local allBirds: Mapping<String, Bird> = import*("**/bird.pkl")
|
||||
|
||||
environment: "prod"|"qa"
|
||||
|
||||
cluster: String
|
||||
|
||||
myBird = allBirds["\(environment)/\(cluster)/bird.pkl"] // <1>
|
||||
----
|
||||
In Pkl 0.26 and below, all modules matching `**/bird.pkl` are imported when `allBirds` is accessed and typechecked.
|
||||
This can take a long time.
|
||||
In Pkl 0.27, only module `"\(environment)/\(cluster)/bird.pkl"` is imported because only this module is part of the program's output.
|
||||
|
||||
To learn more about this change, consult https://github.com/apple/pkl-evolution/blob/main/spices/SPICE-0010-overhauled-mapping-listing-typechecks.adoc[SPICE-0010].
|
||||
|
||||
=== External readers
|
||||
|
||||
A new feature has been added to allow Pkl to spawn external processes to read resources and modules (https://github.com/apple/pkl/pull/660[#660], https://github.com/apple/pkl/pull/762[#762], https://github.com/apple/pkl/pull/766[#766], https://github.com/apple/pkl/pull/770[#770]).
|
||||
|
||||
Today, users who use Pkl as a library can define custom module and resource readers.
|
||||
This allows authors to extend how Pkl performs I/O.
|
||||
|
||||
For example, users can implement a reader that reads the `secret:` scheme, where they define exactly how the bytes are fetched in the host runtime.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
result = read("secret:mypassword") // <1>
|
||||
----
|
||||
<1> `secret:` is a custom scheme defined by the host runtime.
|
||||
|
||||
However, CLI users have been left out.
|
||||
|
||||
In Pkl 0.27, a new extension point is added to allow users to implement module and resource readers as external processes.
|
||||
When run, Pkl will spawn the external process, and talk to the process via xref:bindings-specification:message-passing-api.adoc[message passing].
|
||||
|
||||
To learn more about this feature, consult https://github.com/apple/pkl-evolution/blob/main/spices/SPICE-0009-external-readers.adoc[SPICE-0009].
|
||||
|
||||
Thanks to https://github.com/HT154[@HT154] for contributing the feature!
|
||||
|
||||
[[import-analysis]]
|
||||
=== Import analysis API
|
||||
|
||||
A new API has been added to analyze the import graph of Pkl modules (https://github.com/apple/pkl/pull/695[#695]).
|
||||
|
||||
This API comes in four forms:
|
||||
|
||||
1. A standard library module: `pkl:analyze`
|
||||
2. A CLI command: `pkl analyze imports`
|
||||
3. A Java API: `org.pkl.core.Analyzer`
|
||||
4. A Gradle API: `org.pkl.gradle.task.AnalyzeImportsTask`
|
||||
|
||||
Some use-cases for this API are:
|
||||
|
||||
* For build tools to perform out-of-date checks. Build tools can invalidate a cached result if any of the transitive modules have changed.
|
||||
* Static code analysis, to determine how Pkl modules depend on each other.
|
||||
|
||||
With this API, xref:pkl-gradle:index.adoc[] now by default <<transitive-modules-computed-by-default,computes the transitive modules>> for many of its tasks.
|
||||
|
||||
Here is an example of the CLI in use:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
pkl analyze imports -f json myModule.pkl # <1>
|
||||
----
|
||||
<1> `-f` means: produce output in JSON.
|
||||
|
||||
Produces:
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"imports": {
|
||||
"file:///my/proj/myModule.pkl": [
|
||||
{
|
||||
"uri": "projectpackage://example.com/birds@1.0.0#/Bird.pkl"
|
||||
}
|
||||
],
|
||||
"projectpackage://example.com/birds@1.0.0#/Bird.pkl": []
|
||||
},
|
||||
"resolvedImports": {
|
||||
"file:///my/proj/myModule.pkl": "file:///my/proj/myModule.pkl",
|
||||
"projectpackage://example.com/birds@1.0.0#/Bird.pkl": "file:///my/birds/Bird.pkl"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
From this output, we can see that `myModule.pkl` imports `Bird.pkl` from the `birds` package.
|
||||
We can also see that the module `projectpackage://example.com/birds@1.0.0#/Bird.pkl` resolves to disk location `\file:///my/birds/Bird.pkl` (we can deduce that `birds` is a xref:language-reference:index.adoc#local-dependencies[local dependency]).
|
||||
|
||||
To learn more about this feature, consult https://github.com/apple/pkl-evolution/blob/main/spices/SPICE-0001-import-graph-analyzer-api.adoc[SPICE-0001].
|
||||
|
||||
== Noteworthy [small]#🎶#
|
||||
|
||||
Ready when you need them.
|
||||
|
||||
=== Colored output
|
||||
|
||||
The Pkl CLI will now emit some messages in color (https://github.com/apple/pkl/pull/552[#552], https://github.com/apple/pkl/pull/746[#746], https://github.com/apple/pkl/pull/771[#771], https://github.com/apple/pkl/pull/779[#779]).
|
||||
|
||||
Here is a sneak peek of colored error messages in action.
|
||||
|
||||
image::error_sample.png[syntax highlighted output]
|
||||
|
||||
Thanks to https://github.com/thomaspurchas[@thomaspurchas] for contributing to this feature!
|
||||
|
||||
=== `const local` object members
|
||||
|
||||
The `const` modifier can be applied to object members, provided that they are also `local` (https://github.com/apple/pkl/pull/678[#678]).
|
||||
|
||||
Currently, regular object members are not allowed to have the `const` modifier.
|
||||
This introduces an artificial pain point.
|
||||
|
||||
For example, given the following module:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
amends "Bird.pkl"
|
||||
|
||||
import "Bird.pkl"
|
||||
|
||||
local northAmerica = "North America"
|
||||
|
||||
local typealias NorthAmericanBird = Bird(this.origin == northAmerica) // <1>
|
||||
----
|
||||
<1> Error: cannot reference `northAmerica` from here because it is not `const`.
|
||||
|
||||
This is invalid code, because this typealias is referencing a non-const value on the enclosing module.
|
||||
However, is not possible fix this by adding the `const` modifier to `northAmerica`.
|
||||
This is because this module `amends "Bird.pkl"`, which means that this module is considered a regular object and not a class.
|
||||
This means that any members declared here are _object members_, and not _class members_.
|
||||
|
||||
In Pkl 0.27, a new rule is introduced to allow the `const` modifier to be applied to object members, provided that they are also `local`.
|
||||
|
||||
This change affects object properties, as well as object methods.
|
||||
|
||||
To read more about this design, consult https://github.com/apple/pkl-evolution/blob/main/spices/SPICE-0011-const-object-members.adoc[SPICE-0011].
|
||||
|
||||
=== Pkl CLI changes
|
||||
|
||||
==== New CLI Flags
|
||||
|
||||
Some new common flags have been added to the CLI (https://github.com/apple/pkl/pull/660[#660], https://github.com/apple/pkl/pull/746[#746]).
|
||||
|
||||
|===
|
||||
|Flag |Description
|
||||
|
||||
|`--color`
|
||||
|Format messages with ANSI color codes
|
||||
|
||||
|`--external-module-reader`
|
||||
|Shell out to a process to read certain modules.
|
||||
|
||||
|`--external-resource-reader`
|
||||
|Shell out to a process to read certain resources.
|
||||
|===
|
||||
|
||||
==== New command: `pkl analyze imports`
|
||||
|
||||
As part of the set of APIs added for <<import-analysis,import analysis>>, a new subcommand has been added called `analyze imports` (https://github.com/apple/pkl/pull/695[#695]).
|
||||
|
||||
For details, consult the xref:pkl-cli:index.adoc#command-analyze-imports[CLI documentation].
|
||||
|
||||
=== Kotlin/Java code generator improvements
|
||||
|
||||
Various improvements have been made to the Kotlin and Java code generators (https://github.com/apple/pkl/pull/705[#705], https://github.com/apple/pkl/pull/710[#710], https://github.com/apple/pkl/pull/714[#714], https://github.com/apple/pkl/pull/721[#721], https://github.com/apple/pkl/pull/729[#729]).
|
||||
|
||||
==== Java codegen improvements
|
||||
|
||||
* Only generate `hashCode()`, `equals()`, and `toString()` methods for Java classes that are instantiable.
|
||||
* Add support for Spring Boot 3.
|
||||
* Make module classes also implement serializable.
|
||||
* Make empty Java classes instantiable.
|
||||
|
||||
==== Kotlin codegen improvements
|
||||
|
||||
* Skip generation of `copy()`, `equals()`, `hashCode()`, `toString()` methods for abstract Kotlin classes.
|
||||
* Don't implement `Serializable` for abstract classes
|
||||
* Add support for Spring Boot 3.
|
||||
|
||||
Thanks to https://github.com/translatenix[@translatenix] for contributing these improvements!
|
||||
|
||||
=== Gradle Plugin changes
|
||||
|
||||
==== New `AnalyzeImportsTask`
|
||||
|
||||
A new task called `org.pkl.gradle.task.AnalyzeImportsTask` is introduced (https://github.com/apple/pkl/pull/695[#695]).
|
||||
|
||||
This task is the Gradle analogy to `pkl analyze imports`.
|
||||
|
||||
Example:
|
||||
|
||||
[tabs]
|
||||
====
|
||||
build.gradle::
|
||||
+
|
||||
[source,groovy]
|
||||
----
|
||||
pkl {
|
||||
analyzers {
|
||||
imports {
|
||||
appConfig {
|
||||
sourceModules.add(file("src/main/resources/appConfig.pkl"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
build.gradle.kts::
|
||||
+
|
||||
[source,kotlin]
|
||||
----
|
||||
pkl {
|
||||
analyzers {
|
||||
imports {
|
||||
register("appConfig") {
|
||||
sourceModules.add(file("src/main/resources/appConfig.pkl"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
For more details, consult the xref:pkl-gradle:index.adoc#analyze-imports[documentation].
|
||||
|
||||
==== Tracked file outputs
|
||||
|
||||
Tasks created by the Pkl plugin now declare tracked output files (https://github.com/apple/pkl/pull/403[#403]).
|
||||
|
||||
This means that downstream tasks do not need to declare an explicit dependency on the Pkl task.
|
||||
|
||||
For example, assuming that `evalPkl` is an `EvalTask`:
|
||||
|
||||
.build.gradle.kts
|
||||
[source,diff]
|
||||
----
|
||||
val myGradleTask by tasks.registering {
|
||||
inputs.files(evalPkl)
|
||||
- dependsOn(evalPkl) // <1>
|
||||
}
|
||||
----
|
||||
<1> No longer necessary to declare this dependency.
|
||||
|
||||
[[transitive-modules-computed-by-default]]
|
||||
==== `transitiveModules` computed by default
|
||||
|
||||
The `transitiveModules` property of a task is now computed by building the import graph of the source modules (https://github.com/apple/pkl/pull/695[#695]).
|
||||
|
||||
This means that Pkl-related tasks no longer need to declare their set of transitive modules, because the pkl-gradle plugin will compute this automatically.
|
||||
|
||||
NOTE: This adds latency to each task. To opt out of this behavior, set `transitiveModules` explicitly.
|
||||
|
||||
=== Standard library changes
|
||||
|
||||
==== Additions to `pkl:base`
|
||||
|
||||
New properties and methods have been added to the classes of `pkl:base` (https://github.com/apple/pkl/pull/666[#666], https://github.com/apple/pkl/pull/683[#683]).
|
||||
|
||||
New properties and methods have been added to {uri-stdlib-Listing}[`Listing`] and {uri-stdlib-Mapping}[`Mapping`].
|
||||
|
||||
One of the goals of this change is to improve the experience of authoring constraints.
|
||||
This eliminates the need to convert to collection types as often.
|
||||
|
||||
The added properties and methods are:
|
||||
|
||||
* {uri-stdlib-Listing}#first[`Listing.first`]
|
||||
* {uri-stdlib-Listing}#firstOrNull[`Listing.firstOrNull`]
|
||||
* {uri-stdlib-Listing}#last[`Listing.last`]
|
||||
* {uri-stdlib-Listing}#lastOrNull[`Listing.lastOrNull`]
|
||||
* {uri-stdlib-Listing}#single[`Listing.single`]
|
||||
* {uri-stdlib-Listing}#singleOrNull[`Listing.singleOrNull`]
|
||||
* {uri-stdlib-Listing}#every()[`Listing.every()`]
|
||||
* {uri-stdlib-Listing}#any()[`Listing.any()`]
|
||||
* {uri-stdlib-Listing}#contains()[`Listing.contains()`]
|
||||
* {uri-stdlib-Mapping}#containsValue()[`Mapping.containsValue()`]
|
||||
* {uri-stdlib-Mapping}#every()[`Mapping.every()`]
|
||||
* {uri-stdlib-Mapping}#any()[`Mapping.any()`]
|
||||
|
||||
With this, the following change can be made to existing constraints:
|
||||
|
||||
[source,diff]
|
||||
----
|
||||
-ipAddresses: Listing<String>(toList().contains("127.0.0.1"))
|
||||
+ipAddresses: Listing<String>(contains("127.0.0.1"))
|
||||
----
|
||||
|
||||
Additionally, a new method is added to `String`, called {uri-stdlib-String}#splitLimit()[`String.splitLimit()`].
|
||||
|
||||
==== Additions to `pkl:EvaluatorSettings`
|
||||
|
||||
New properties have been added to `pkl:EvaluatorSettings` (https://github.com/apple/pkl/pull/660[#660], https://github.com/apple/pkl/pull/746[#746]).
|
||||
|
||||
These are:
|
||||
|
||||
* {uri-stdlib-evaluatorSettingsModule}/#color[`color`]
|
||||
* {uri-stdlib-evaluatorSettingsModule}/#externalModuleReaders[`externalModuleReaders`]
|
||||
* {uri-stdlib-evaluatorSettingsModule}/#externalResourceReaders[`externalResourceReaders`]
|
||||
|
||||
==== `String` to `Number` conversion improvements.
|
||||
|
||||
The `String` to `Number` converter methods, for example, {uri-stdlib-StringToInt}[`String.toInt()`], can now handle underscore separators (https://github.com/apple/pkl/pull/578[#578], https://github.com/apple/pkl/pull/580[#580]).
|
||||
|
||||
This better aligns with the source code representation of xref:language-reference:index.adoc#integers[number literals].
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
myNum = "1_000".toInt() // <1>
|
||||
----
|
||||
<1> Result: `1000`
|
||||
|
||||
==== New module: `pkl:analyze`
|
||||
|
||||
As part of <<import-analysis>>, a new standard library module is added called `pkl:analyze` (https://github.com/apple/pkl/pull/695[#695]).
|
||||
|
||||
This module provides an API for computing the total import graph given a set of input modules.
|
||||
This API treats the inputs as entrypoints, and produces a graph representing the entire dependency tree, including transitive imports.
|
||||
|
||||
Example:
|
||||
[source,pkl]
|
||||
----
|
||||
import "pkl:analyze"
|
||||
|
||||
importGraph: analyze.ImportGraph = analyze.importGraph(Set("file:///path/to/my/module.pkl"))
|
||||
----
|
||||
|
||||
For details, see the {uri-stdlib-analyzeModule}[documentation].
|
||||
|
||||
=== Annotations on `PklProject` added to packages
|
||||
|
||||
When creating packages, some annotations on a `PklProject` will affect how pkldoc generates documentation.
|
||||
|
||||
* `@Unlisted`: Omit the package from publishing documentation.
|
||||
* `@Deprecated`: Add information on the package to show that it is deprecated.
|
||||
|
||||
Example:
|
||||
|
||||
.PklProject
|
||||
[source,pkl]
|
||||
----
|
||||
@Deprecated
|
||||
amends "pkl:Project"
|
||||
----
|
||||
|
||||
=== Test report improvements
|
||||
|
||||
The report generated from `pkl test` has been overhauled and improved (https://github.com/apple/pkl/pull/498[#498], https://github.com/apple/pkl/pull/628[#682], https://github.com/apple/pkl/pull/738[#738], https://github.com/apple/pkl/pull/771[#771]).
|
||||
|
||||
* Tests are grouped into either the `facts` or `examples` section.
|
||||
* A summary line is added, describing how many tests have passed and failed, and how many assertions have passed and failed.
|
||||
* Test results are colored.
|
||||
* The ✅ and ❌ emojis are replaced with ✔ and ✘.
|
||||
* Thrown errors are reported within the test.
|
||||
|
||||
Here is a sneak peek of the new test result output.
|
||||
|
||||
image::test_sample.png[]
|
||||
|
||||
Thanks to https://github.com/jjmaestro[@jjmaestro] for contributing to this improvement!
|
||||
|
||||
=== Java API additions
|
||||
|
||||
==== New API: `org.pkl.core.Analyzer`
|
||||
|
||||
As part of <<import-analysis>>, a new Java API called `org.pkl.core.Analyzer` is introduced (https://github.com/apple/pkl/pull/695[#695]).
|
||||
|
||||
==== New methods
|
||||
|
||||
The following methods are added:
|
||||
|
||||
**pkl-executor**
|
||||
|
||||
* `org.pkl.executor.ExecutorException.getPklVersion`
|
||||
* `org.pkl.executor.ExecutorException.ExecutorException(java.lang.String, java.lang.Throwable, java.lang.String)`
|
||||
|
||||
**pkl-core**
|
||||
|
||||
* `org.pkl.core.module.ModuleKeyFactories.externalProcess(java.lang.String, org.pkl.core.externalreader.ExternalReaderProcess)`
|
||||
* `org.pkl.core.module.ModuleKeyFactories.externalProcess(java.lang.String, org.pkl.core.externalreader.ExternalReaderProcess, long)`
|
||||
|
||||
== Breaking Changes [small]#💔#
|
||||
|
||||
Things to watch out for when upgrading.
|
||||
|
||||
=== Java API breaking changes
|
||||
|
||||
The following Java APIs have breaking changes:
|
||||
|
||||
|===
|
||||
|Class/method | Breaking change
|
||||
|
||||
|`org.pkl.core.runtime.TestResults`
|
||||
|Moved to `org.pkl.core.TestResults`, turned into a record, and largely restructured.
|
||||
|
||||
|`org.pkl.core.module.ModuleKeyFactories.closeQuietly`
|
||||
|Deprecated for removal in favor of `org.pkl.core.Closeables.closeQuietly`.
|
||||
|===
|
||||
|
||||
=== Spring Boot 2 support dropped
|
||||
|
||||
The Java code generator no longer supports Spring Boot 2.x (https://github.com/apple/pkl/pull/729[#729]).
|
||||
|
||||
Spring Boot 2 users can continue to use the Pkl 0.26 code generator.
|
||||
|
||||
=== `pkl test` considered failing when writing examples
|
||||
|
||||
If running `pkl test` results in `pkl-expected.pcf` files being written, the test now exits with exit code `10` (https://github.com/apple/pkl/pull/738[#738]).
|
||||
|
||||
Additionally, the junit reports will consider the test as failing.
|
||||
|
||||
=== `Listing` and `Mapping` typecheck changes
|
||||
|
||||
Due to changes to <<typecheck-improvements,Listing and Mapping typechecking>>, some previously failing programs now succeed.
|
||||
This can happen when erroneous code is never evaluated because it does not affect program output:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
local myNumbers: Listing<Int> = new { 1; 2; "uh oh" }
|
||||
result = myNumbers[0] // <1>
|
||||
----
|
||||
<1> In Pkl 0.26 and below, throws a type mismatch error.
|
||||
+
|
||||
In Pkl 0.27, yields `1`.
|
||||
|
||||
== Miscellaneous [small]#🐸#
|
||||
|
||||
* Make pkl-doc top box include a preview of the rest of module-level documentation (https://github.com/apple/pkl/pull/570[#570]).
|
||||
* Module `pkl-core` now has a dependency on `org.msgpack:msgpack-core` (https://github.com/apple/pkl/pull/660[#660]). Users concerned about potential version conflicts can use one of Pkl's shaded fat JARs (`pkl-config-java-all`, `pkl-tools`).
|
||||
* Make PklProject.deps.json files end in a newline (https://github.com/apple/pkl/pull/664[#644]).
|
||||
* Fix invalid syntax of code examples in stdlib doc comments (https://github.com/apple/pkl/pull/703[#703]).
|
||||
* Update Java dependencies (https://github.com/apple/pkl/pull/689[#689], https://github.com/apple/pkl/pull/767[#767]).
|
||||
* Add jbang catalog support (https://github.com/apple/pkl/pull/655[#655]).
|
||||
* Documentation improvements (https://github.com/apple/pkl/pull/623[#623], https://github.com/apple/pkl/pull/680[#680], https://github.com/apple/pkl/pull/682[#682], https://github.com/apple/pkl/pull/685[#685], https://github.com/apple/pkl/pull/687[#687], https://github.com/apple/pkl/pull/703[#703], https://github.com/apple/pkl/pull/704[#704], https://github.com/apple/pkl/pull/715[#715], https://github.com/apple/pkl/pull/730[#730], https://github.com/apple/pkl/pull/753[#753]).
|
||||
|
||||
== Bug Fixes [small]#🐜#
|
||||
|
||||
The following bugs have been fixed.
|
||||
|
||||
* CLI `--property` flags containing `=` in property values are not parsed correctly (https://github.com/apple/pkl/issues/630[#630]).
|
||||
* Thrown `PklBugException` when reading assets from a local project dependency (https://github.com/apple/pkl/issues/641[#641]).
|
||||
* Thrown `PklBugException` when PklProjects have a cyclical local dependency (https://github.com/apple/pkl/pull/731[#731]).
|
||||
* Thrown exception when sending `ReadResourceResponse` or `ReadModuleResponse` where both `contents` and `error` are `null` (https://github.com/apple/pkl/pull/657[#657]).
|
||||
* Double unary minus is evaluated as single unary minus (https://github.com/apple/pkl/pull/697[#697]).
|
||||
* Kotlin compiler fails to compiler generated classes with "copy overrides nothing" for subclasses of abstract classes (https://github.com/apple/pkl/issues/569[#569]).
|
||||
* "Unexpected error" thrown when `Module.output` has its type overridden (https://github.com/apple/pkl/issues/709[#709]).
|
||||
* "Unexpected error" thrown when loading files with non-ASCII characters (https://github.com/apple/pkl/issues/653[#653]).
|
||||
* Type parameters in `new Mapping<TypeA, TypeB>`/`new Listing <Type>` are not checked (https://github.com/apple/pkl/issues/405[#405]).
|
||||
* Comparison methods of `pkl:semver` are incorrect (https://github.com/apple/pkl/issues/772[#772]).
|
||||
|
||||
== Contributors [small]#🙏#
|
||||
|
||||
We would like to thank the contributors to this release (in alphabetical order):
|
||||
|
||||
* https://github.com/djarnis73[@djarnis73]
|
||||
* https://github.com/kasugamirai[@kasugamirai]
|
||||
* https://github.com/KushalP[@KushalP]
|
||||
* https://github.com/jjmaestro[@jjmaestro]
|
||||
* https://github.com/HT154[@HT154]
|
||||
* https://github.com/lamtrinhdev[@lamtrinhdev]
|
||||
* https://github.com/ManuW[@ManuW]
|
||||
* https://github.com/maxandersen[@maxandersen]
|
||||
* https://github.com/netvl[@netvl]
|
||||
* https://github.com/StefMa[@StefMa]
|
||||
* https://github.com/taichi-ishitani[@taichi-ishitani]
|
||||
* https://github.com/thomaspurchas[@thomaspurchas]
|
||||
* https://github.com/translatenix[@translatenix]
|
||||
378
docs/modules/release-notes/pages/0.28.adoc
Normal file
378
docs/modules/release-notes/pages/0.28.adoc
Normal file
@@ -0,0 +1,378 @@
|
||||
= Pkl 0.28 Release Notes
|
||||
:version: 0.28
|
||||
:version-minor: 0.28.2
|
||||
:release-date: February 26th, 2025
|
||||
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
|
||||
:uri-snippet-tests: {uri-github-tree}/pkl-core/src/test/files/LanguageSnippetTests/input
|
||||
:uri-standard-library: {uri-github-tree}/stdlib/
|
||||
:uri-antlr: https://www.antlr.org
|
||||
:wbr: pass:[<wbr />]
|
||||
|
||||
Pkl {version} was released on {release-date}. +
|
||||
[.small]#The latest bugfix release is {version-minor}. (xref:changelog.adoc[All Versions])#
|
||||
|
||||
The next release (0.29) is scheduled for June 2025.
|
||||
To see what's coming in the future, follow the {uri-pkl-roadmap}[Pkl Roadmap].
|
||||
|
||||
Please send feedback and questions to https://github.com/apple/pkl/discussions[GitHub Discussions], or submit an issue on https://github.com/apple/pkl/issues/new[GitHub]. +
|
||||
|
||||
[small]#Pkl is hosted on https://github.com/apple/pkl[GitHub].
|
||||
To get started, follow xref:pkl-cli:index.adoc#installation[Installation].#
|
||||
|
||||
== Highlights [small]#💖#
|
||||
|
||||
News you don't want to miss.
|
||||
|
||||
=== New parser
|
||||
|
||||
Pkl has new parser (https://github.com/apple/pkl/pull/917[#917], https://github.com/apple/pkl/pull/957[#957], https://github.com/apple/pkl/pull/962[#962])!
|
||||
|
||||
The first step to evaluating a program is to parse its source code into a parse tree.
|
||||
Currently, Pkl uses link:{uri-antlr}[ANTLR] to generate parser code from grammar files.
|
||||
|
||||
Using this approach has allowed for rapidly iterating and changing the language's grammar.
|
||||
However, Pkl's grammar has matured; it's not as likely that the grammar will change from one version to the next.
|
||||
Additionally, the current parser's performance has become more painful as projects written in Pkl grow in size.
|
||||
In many cases, parsing can take up most of the time spent during evaluation.
|
||||
|
||||
In 0.28, the ANTLR-generated parser is being replaced by a handwritten parser.
|
||||
In benchmarking tests, this has shown to improve parsing speed by around two orders of magnitude.
|
||||
Here are some quick comparisons between the two parsers, run on a MacBook Pro M4 Max machine, with 5 warmup iterations, and run for 10 iterations:
|
||||
|
||||
|===
|
||||
||Old parser |New parser
|
||||
|
||||
|link:{uri-snippet-tests}[Language snippet tests]
|
||||
|440.8ms
|
||||
|5.9ms
|
||||
|
||||
|link:{uri-standard-library}[Standard library]
|
||||
|136.7msfootnote:[In the `pkl` CLI, the standard library is parsed during compilation rather than during evaluation. As a result, there is no parsing overhead.]
|
||||
|0.8ms
|
||||
|
||||
|All https://github.com/apple/pkl-pantry[pkl-pantry] modules
|
||||
|1424.2ms
|
||||
|7.0ms
|
||||
|===
|
||||
|
||||
== Noteworthy [small]#🎶#
|
||||
|
||||
Ready when you need them.
|
||||
|
||||
=== CLI improvements
|
||||
|
||||
==== Colored help messages
|
||||
|
||||
The `pkl`, `pkldoc`, `pkl-codegen-java`, and `pkl-codegen-kotlin` CLIs now emits help text with colors (https://github.com/apple/pkl/pull/947[#947]).
|
||||
|
||||
Here is a sneak peek:
|
||||
|
||||
image::pkl-cli-help-new.png[new pkl cli help output]
|
||||
|
||||
Thanks to https://github.com/gordonbondon[@gordonbondon] for their contribution!
|
||||
|
||||
==== `jpkl` support on Windows
|
||||
|
||||
The `jpkl` executable is now supported on Windows (https://github.com/apple/pkl/pull/872[#872]).
|
||||
|
||||
`jpkl` is a fat jar that can be executed directly when on macOS and Linux, but current users of Windows are required to execute it with `java -jar <path/to/jpkl>`.
|
||||
|
||||
In 0.28, Windows users can also call execute this command directly.
|
||||
To do so, the filename should be called `jpkl.bat`, and placed in `PATH`.
|
||||
|
||||
=== Type constraint changes
|
||||
|
||||
Type annotations that are executed as a result of calling a constraint expressions now perform an eager typecheck (https://github.com/apple/pkl/pull/964[#964]).
|
||||
|
||||
In Pkl 0.27, we changed how xref:0.27.adoc#typecheck-improvements[typechecks are executed for `Listing` and `Mapping`] types.
|
||||
|
||||
However, this had two unintended side effects:
|
||||
|
||||
For one, error messages from certain failing constraints show `?` in place of values that are failing.
|
||||
|
||||
The following snippet:
|
||||
|
||||
[source%parsed,pkl]
|
||||
----
|
||||
class Bird { name: String }
|
||||
|
||||
bird: Listing<Bird>(firstOneIsQuail) = new {
|
||||
new { name = "Pigeon" }
|
||||
new { name = "Quail" }
|
||||
}
|
||||
|
||||
local firstOneIsQuail = (it: Listing<Bird>) -> it[0].name == "Quail"
|
||||
----
|
||||
|
||||
Produces the following error message:
|
||||
|
||||
[source]
|
||||
----
|
||||
–– Pkl Error ––
|
||||
Type constraint `firstOneIsQuail` violated.
|
||||
Value: new Listing { ?; ? }
|
||||
|
||||
3 | bird: Listing<Bird>(firstOneIsQuail) = new {
|
||||
^^^^^^^^^^^^^^^
|
||||
----
|
||||
|
||||
:fn-typecheck-details: footnote:[See https://github.com/apple/pkl-evolution/blob/main/spices/SPICE-0010-overhauled-mapping-listing-typechecks.adoc#delegating-objects[delegating objects] in SPICE-0010 for more details on this behavior.]
|
||||
|
||||
This is happening because lazy typechecks of mappings and listings will return a _new_ listing. Because the lambda's argument is defined as ``it: Listing<Bird>``, the value being passed into the function body is this new listing{fn-typecheck-details}.
|
||||
|
||||
Secondly, some constraints became less strict, allowing more values to pass.
|
||||
|
||||
The following snippet fails in Pkl 0.26, but passes in Pkl 0.27:
|
||||
|
||||
[source%parsed,pkl]
|
||||
----
|
||||
class Bird { name: String }
|
||||
|
||||
local nonEmpty = (it: Listing<Bird>) -> !it.isEmpty
|
||||
|
||||
birds: Listing(nonEmpty) = new { 1; 2; 3 }
|
||||
----
|
||||
|
||||
This is because the function parameter `it: Listing<Bird>` does not actually check members of the argument until they are accessed, and the function body `!it.isEmpty` does not access any members.
|
||||
|
||||
To address both of these issues, the rule for executing type constraints has changed.
|
||||
When executing a type annotation, mapping and listing typechecks are always _eager_.
|
||||
This means that Pkl will check that each member of the mapping/listing conforms to the type parameter.
|
||||
|
||||
=== Java 22+ support
|
||||
|
||||
Pkl's Java libraries now support Java 22 and higher (https://github.com/apple/pkl/pull/876[#876]).
|
||||
|
||||
Thanks to https://github.com/sgammon[@sgammon] for their contribution!
|
||||
|
||||
=== New standard library method
|
||||
|
||||
The `pkl:math` standard library module has a new method, called {uri-stdlib-mathModule}/index.html#atan2()[atan2] (https://github.com/apple/pkl/pull/819[#819]).
|
||||
It computes the https://en.wikipedia.org/wiki/Atan2[2-argument arctangent].
|
||||
|
||||
Thanks to https://github.com/gordonbondon[@gordonbondon] for their contribution!
|
||||
|
||||
=== Overhauled for-generator implementation
|
||||
|
||||
The implementation of xref:language-reference:index.adoc#for-generators[for-generators] has been overhauled (https://github.com/apple/pkl/pull/844[#844]).
|
||||
|
||||
This fixes some known bugs with the current for-generator implementation, and also improves code health by reducing complexity and removing workarounds and band-aids.
|
||||
|
||||
Thanks to https://github.com/odenix[@odenix] for their contribution!
|
||||
|
||||
=== Java code generator improvements
|
||||
|
||||
Improvements have been made to the Java code generator (https://github.com/apple/pkl/pull/792[#792]).
|
||||
|
||||
In pkl-codegen-java, the `--params-annotation` flag now accepts `none` as a value, which causes the code generator to skip adding annotations to a constructor's parameters.
|
||||
Additionally, the Kotlin API `org.pkl.codegen.java.JavaCodeGeneratorOptions.paramsAnnotation` is now nullable.
|
||||
If null, this also skips adding annotations.
|
||||
|
||||
By default, this annotation is set to `org.pkl.config.java.mapper.Named`, or none if the `--generate-spring-boot-config` flag is set.
|
||||
|
||||
This is useful for those compiling Java code with the `-parameters` flag set, because the pkl-config-java library is able to map into these classes without any extra annotations.
|
||||
|
||||
Thanks to https://github.com/odenix[@odenix] for their contribution!
|
||||
|
||||
=== Kotlin code generator improvements
|
||||
|
||||
Improvements have been made to the Kotlin code generator (https://github.com/apple/pkl/pull/793[#793]).
|
||||
|
||||
Currently, the output of `toString()` on a generated Kotlin class differs depending on if it was generated as a data class or as a regular class.
|
||||
|
||||
In Pkl 0.28, this method produces the same format, and matches the format used by data classes.
|
||||
|
||||
Thanks to https://github.com/odenix[@odenix] for their contribution!
|
||||
|
||||
=== pkldoc improvements
|
||||
|
||||
pkldoc has a new flag to write real files instead of symlinks (https://github.com/apple/pkl/pull/824[#824]).
|
||||
|
||||
Currently, pkldoc creates a symlink called "current", which points to the latest non-prerelease version of a package.
|
||||
However, these symlinks can be problematic for some systems.
|
||||
|
||||
A new flag, `--no-symlinks`, and a similarly named Gradle property, `noSymlinks`, instructs pkldoc to write real files instead of symlinks.
|
||||
|
||||
Thanks to https://github.com/netvl[@netvl] for their contributions!
|
||||
|
||||
=== `jar:nested:` URIs are accepted by default
|
||||
|
||||
To improve integration with Spring Boot, the Pkl evaluator by default now accepts module URIs starting with `jar:nested:` (https://github.com/apple/pkl/pull/895[#895]).
|
||||
|
||||
The `--allowed-modules` flag (and the equally named option in other APIs) can be used to configure the set of allowed modules.
|
||||
|
||||
== Breaking Changes [small]#💔#
|
||||
|
||||
Things to watch out for when upgrading.
|
||||
|
||||
=== Stricter grammar
|
||||
|
||||
As a result of implementing a new parser, the following previously accepted grammar is no longer valid (https://github.com/apple/pkl/pull/917[#917]).
|
||||
|
||||
==== Inline object entries
|
||||
|
||||
When declaring multiple xref:language-tutorial:01_basic_config.adoc#entries[entries] on the same line, a semicolon is now required to separate them.
|
||||
|
||||
The following code snippet is currently valid, and becomes a syntax error in 0.28.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
obj { ["one"] = 1 ["two"] = 2 }
|
||||
----
|
||||
|
||||
To fix, insert a semicolon between the two entries:
|
||||
|
||||
[source,diff]
|
||||
----
|
||||
-obj { ["one"] = 1 ["two"] = 2 }
|
||||
+obj { ["one"] = 1; ["two"] = 2 }
|
||||
----
|
||||
|
||||
==== String escapes
|
||||
|
||||
When using xref:language-reference:index.adoc#custom-string-delimiters[custom string delimiters], the escape sequence becomes backslash (`\`) plus the number of pounds used to delimit the string.
|
||||
|
||||
Due to a parser bug, any extra pounds after this escape sequence are also permitted.
|
||||
|
||||
In Pkl 0.28, this becomes a syntax error.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
foo = "foo \#(bar)" // Invalid character escape sequence `\#`.
|
||||
----
|
||||
|
||||
==== Whitespace between generator members
|
||||
|
||||
Inline object spreads, for generators, and when generators all now require either whitespace or a semicolon separator.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
foo { ...bar...baz } // Syntax error
|
||||
----
|
||||
|
||||
=== Minimum Gradle version bump
|
||||
|
||||
The minimum Gradle version for the xref:main:pkl-gradle:index.adoc[Gradle Plugin] has been bumped to 8.2 (https://github.com/apple/pkl/pull/901[#901]).
|
||||
|
||||
=== Minimum Kotlin version bump
|
||||
|
||||
For users of Pkl's Kotlin libraries, the minimum Kotlin version has been bumped to 2.0 (https://github.com/apple/pkl/pull/900[#900]).
|
||||
|
||||
=== Java/Kotlin API breaking changes
|
||||
|
||||
Breaking changes have been made to the Java/Kotlin APIs (https://github.com/apple/pkl/pull/748[#748], https://github.com/apple/pkl/pull/749[#749], https://github.com/apple/pkl/pull/776[#776], https://github.com/apple/pkl/pull/793[#793], https://github.com/apple/pkl/pull/808[#808], https://github.com/apple/pkl/pull/810[#810]).
|
||||
|
||||
|===
|
||||
|API |Breakage
|
||||
|
||||
| org.pkl.core.resource{wbr}.Resource
|
||||
| Converted into a record; previous getter methods are deprecated.
|
||||
|
||||
| org.pkl.core.project{wbr}.Package
|
||||
| Converted into a record; previous getter methods are deprecated.
|
||||
|
||||
| org.pkl.core.Member{wbr}.SourceLocation
|
||||
| Converted into a record; previous getter methods are deprecated.
|
||||
|
||||
| org.pkl.core{wbr}.Release
|
||||
| Converted into a record; previous getter methods are deprecated.
|
||||
|
||||
| org.pkl.core.Release{wbr}.SourceCode
|
||||
| Converted into a record; previous getter methods are deprecated.
|
||||
|
||||
| org.pkl.core.Release{wbr}.Documentation
|
||||
| Converted into a record; previous getter methods are deprecated.
|
||||
|
||||
| org.pkl.core.Release{wbr}.StandardLibrary
|
||||
| Converted into a record; previous getter methods are deprecated.
|
||||
|
||||
| org.pkl.core.project{wbr}.DeclaredDependencies
|
||||
| Converted into a record; previous getter methods are deprecated.
|
||||
|
||||
| org.pkl.core.evaluatorSettings{wbr}.PklEvaluatorSettings{wbr}.Proxy{wbr}.create
|
||||
| Deprecated; use the constructor instead.
|
||||
|
||||
| org.pkl.core.module{wbr}.ExternalModuleResolver
|
||||
| Moved into package org.pkl.core.externalreader
|
||||
|
||||
| org.pkl.core.resource{wbr}.ExternalResourceResolver
|
||||
| Moved into package org.pkl.core.externalreader
|
||||
|
||||
| org.pkl.core.messaging{wbr}.MessageTransportModuleResolver
|
||||
| Renamed to ExternalModuleResolverImpl, made package-private
|
||||
|
||||
| org.pkl.core.messaging{wbr}.MessageTransportResourceResolver
|
||||
| Renamed to ExternalResourceResolverImpl, made package-private
|
||||
|
||||
| org.pkl.core.module{wbr}.ExternalModuleResolver{wbr}.Spec
|
||||
| Replaced with record org.pkl.core.externalreader.ModuleReaderSpec
|
||||
|
||||
| org.pkl.core.resource{wbr}.ExternalResourceResolver{wbr}.Spec
|
||||
| Replaced with record org.pkl.core.externalreader.ResourceReaderSpec
|
||||
|
||||
| org.pkl.core.messaging{wbr}.CreateEvaluatorRequest
|
||||
| Changed properties `allowedModules` and `allowedResources` to be of type `List<String>` instead of `List<Pattern>`
|
||||
|
||||
| org.pkl.codegen.kotlin{wbr}.KotlinCodegenOptions
|
||||
| Renamed to org.pkl.codegen.kotlin.KotlinCodeGeneratorOptions
|
||||
|
||||
| org.pkl.codegen.kotlin{wbr}.CliKotlinCodeGeneratorOptions{wbr}.toKotlinCodegenOptions
|
||||
| Deprecated without replacement
|
||||
|
||||
| org.pkl.codegen.java{wbr}.JavaCodegenOptions
|
||||
| Renamed to org.pkl.codegen.java.JavaCodeGeneratorOptions
|
||||
|
||||
| org.pkl.codegen.java{wbr}.CliJavaCodeGeneratorOptions{wbr}.toJavaCodegenOptions()
|
||||
| Deprecated without replacement
|
||||
|===
|
||||
|
||||
=== Fat jars no longer shade Truffle
|
||||
|
||||
Pkl publishes two fat jars to Maven Central: https://central.sonatype.com/artifact/org.pkl-lang/pkl-tools[pkl-tools], and https://central.sonatype.com/artifact/org.pkl-lang/pkl-config-java-all[pkl-config-java-all].
|
||||
|
||||
Due a version bump in the Truffle library, the package `com.oracle.truffle` can no longer be shaded.
|
||||
|
||||
For users that use both Pkl and other Truffle languages, this means that their version of Truffle should match Pkl's version.
|
||||
|
||||
== Miscellaneous [small]#🐸#
|
||||
|
||||
* Documentation improvements (https://github.com/apple/pkl/pull/792[#792], https://github.com/apple/pkl/pull/846[#846], https://github.com/apple/pkl/pull/860[#860], https://github.com/apple/pkl/pull/892[#892], https://github.com/apple/pkl/pull/921[#921], https://github.com/apple/pkl/pull/937[#937], https://github.com/apple/pkl/pull/943[#943], https://github.com/apple/pkl/pull/944[#944], https://github.com/apple/pkl/pull/955[#955], https://github.com/apple/pkl/pull/956[#956], https://github.com/apple/pkl/pull/973[#973]).
|
||||
* The repository now requires Java 21 or higher to build (https://github.com/apple/pkl/pull/876[#876]).
|
||||
* Enable multi-jdk testing via `-DmultiJdkTesting=true` flag when building Pkl (https://github.com/apple/pkl/pull/876[#876]).
|
||||
* Allow setting commit id via `-DcommitId` flag when building Pkl (https://github.com/apple/pkl/pull/954[#954]).
|
||||
|
||||
== Bugs fixed [small]#🐜#
|
||||
|
||||
The following bugs have been fixed.
|
||||
|
||||
[smaller]
|
||||
* Optimization: `const` members should be cached for all children in the prototype chain (https://github.com/apple/pkl/issues/508[#508])
|
||||
* codegen-kotlin: Use same toString() representation for data classes and regular classes (https://github.com/apple/pkl/issues/717[#717])
|
||||
* Late-bound values of iteratees within nested for/spread fail to resolve for-generator variables (https://github.com/apple/pkl/issues/741[#741])
|
||||
* codegen-java/kotlin: Fix generation of equals/hashCode methods (https://github.com/apple/pkl/pull/802[#802])
|
||||
* Not possible to render mapping with Int keys in YAML (https://github.com/apple/pkl/issues/878[#878])
|
||||
* Parser accepts wrong string escapes (https://github.com/apple/pkl/issues/888[#888])
|
||||
* Downstream native-image embedders are broken (https://github.com/apple/pkl/issues/907[#907])
|
||||
* Failed type constraint error messages do not show forced members (https://github.com/apple/pkl/issues/918[#918])
|
||||
* ANTLR incompatibilities (https://github.com/apple/pkl/issues/927[#927])
|
||||
* Doc comments with interleaving comments result in an error (https://github.com/apple/pkl/issues/931[#931])
|
||||
* Spread elements inside an object body don't need separators (https://github.com/apple/pkl/issues/932[#932])
|
||||
* Correctly set allowed modules/resoures when external reader scheme contain regex control characters (https://github.com/apple/pkl/pull/941[#941])
|
||||
* Bad import analysis fails with "None (cause has no message)" (https://github.com/apple/pkl/issues/949[#949])
|
||||
|
||||
== Contributors [small]#🙏#
|
||||
|
||||
We would like to thank the contributors to this release (in alphabetical order):
|
||||
|
||||
* https://github.com/gordonbondon[@gordonbondon]
|
||||
* https://github.com/HT154[@HT154]
|
||||
* https://github.com/jsoref[@jsoref]
|
||||
* https://github.com/KushalP[@KushalP]
|
||||
* https://github.com/netvl[@netvl]
|
||||
* https://github.com/odenix[@odenix]
|
||||
* https://github.com/romacafe[@romacafe]
|
||||
* https://github.com/sgammon[@sgammon]
|
||||
* https://github.com/sorcix[@sorcix]
|
||||
* https://github.com/stanleyycheung[@stanleyycheung]
|
||||
419
docs/modules/release-notes/pages/0.29.adoc
Normal file
419
docs/modules/release-notes/pages/0.29.adoc
Normal file
@@ -0,0 +1,419 @@
|
||||
= Pkl 0.29 Release Notes
|
||||
:version: 0.29
|
||||
:version-minor: 0.29.1
|
||||
:release-date: July 24th, 2025
|
||||
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
|
||||
Pkl {version} was released on {release-date}. +
|
||||
[.small]#The latest bugfix release is {version-minor}. (xref:changelog.adoc[All Versions])#
|
||||
|
||||
This release brings support for working with binary data, and also a new setting to control HTTP rewriting.
|
||||
|
||||
The next release (0.30) is scheduled for October 2025.
|
||||
To see what's coming in the future, follow the {uri-pkl-roadmap}[Pkl Roadmap].
|
||||
|
||||
Please send feedback and questions to https://github.com/apple/pkl/discussions[GitHub Discussions], or submit an issue on https://github.com/apple/pkl/issues/new[GitHub]. +
|
||||
|
||||
[small]#Pkl is hosted on https://github.com/apple/pkl[GitHub].
|
||||
To get started, follow xref:pkl-cli:index.adoc#installation[Installation].#
|
||||
|
||||
== Highlights [small]#💖#
|
||||
|
||||
[[bytes-standard-library-class]]
|
||||
=== `Bytes` standard library class
|
||||
|
||||
A new standard library class is introduced, called `Bytes` (https://github.com/apple/pkl/pull/1019[#1019]).
|
||||
|
||||
Currently, Pkl does not have a built-in way to describe binary data.
|
||||
In situations where binary data is needed, the common pattern is to use a Base64 string.
|
||||
This is sufficient in simple cases, but still introduces many shortcomings:
|
||||
|
||||
1. `pkl eval` can only produce UTF-8 encoded strings.
|
||||
2. It is not possible to compute the checksum of binary content (except in the case of `read()`).
|
||||
3. It is hard to interop with configuration formats that allow binary data.
|
||||
4. It is hard to do transformations on binary data.
|
||||
|
||||
To address these shortcomings, the `Bytes` class is introduced.
|
||||
This is a data type representing a sequence of bytes.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
myBytes = Bytes(0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21) // <1>
|
||||
----
|
||||
<1> ASCII bytes for the string "Hello, World!"
|
||||
|
||||
To learn more about this feature, consult https://github.com/apple/pkl-evolution/blob/main/spices/SPICE-0013-bytes-standard-library.adoc[SPICE-0013].
|
||||
|
||||
==== Emitting binary output
|
||||
|
||||
A new property called `bytes` is added to `FileOutput`.
|
||||
The CLI has been changed to evaluate this property, and write its contents to the designated output location.
|
||||
|
||||
This change means that Pkl modules can now output binary content.
|
||||
For example, here is a simple module that outputs bytes:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
output {
|
||||
bytes = Bytes(1, 2, 3, 4) // <1>
|
||||
}
|
||||
----
|
||||
<1> Write bytes 1, 2, 3, 4
|
||||
|
||||
The same change applies when evaluating in multiple-file output mode.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
output {
|
||||
files {
|
||||
["foo.bin"] {
|
||||
bytes = Bytes(1, 2, 3, 4) // <1>
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> Write bytes 1, 2, 3, 4 to a file called `foo.bin`.
|
||||
|
||||
==== Rendering `Bytes`
|
||||
|
||||
Out of the box, only the `plist` and `pcf` formats are able to render `Bytes`.
|
||||
For other formats, a renderer needs to be defined.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
output {
|
||||
renderer = new JsonRenderer {
|
||||
[Bytes] = (it) -> it.base64 // <1>
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> Render bytes as a base64 string in JSON.
|
||||
|
||||
==== Using `Bytes` from language bindings
|
||||
|
||||
Users of Pkl's language bindings also benefit from the new type.
|
||||
When using code generation, the `Bytes` data type will turn into the following types:
|
||||
|
||||
|===
|
||||
|Language |Type
|
||||
|
||||
|Java
|
||||
|`byte[]`
|
||||
|
||||
|Kotlin
|
||||
|`ByteArray`
|
||||
|
||||
|Go
|
||||
|`[]byte`
|
||||
|
||||
|Swift
|
||||
|`[UInt8]`
|
||||
|===
|
||||
|
||||
Maintainers of other language bindings are encouraged to map `Bytes` into the corresponding binary type in their language.
|
||||
|
||||
==== `Bytes` versus `List<UInt8>`
|
||||
|
||||
Conceptually, `Bytes` is very similar to `List<UInt8>`, because both are data types that describe sequences of `UInt8` values.
|
||||
However, they have different performance characteristics.
|
||||
A `List` is a https://en.wikipedia.org/wiki/Persistent_data_structure[persistent data structure].
|
||||
This means that creating modified copies of lists is very cheap.
|
||||
|
||||
However, lists have more overhead per element.
|
||||
A `List<UInt8>` with 1000 elements takes up about 5.4 kilobytes of heap space, whereas the same data in `Bytes` takes roughly 1 kilobyte.
|
||||
|
||||
=== HTTP Rewrites and Package Mirroring
|
||||
|
||||
A new evaluator setting is introduced, which rewrites URLs before making outbound HTTP calls (https://github.com/apple/pkl/pull/1062[#1062], https://github.com/apple/pkl/pull/1127[#1127], https://github.com/apple/pkl/pull/1133[#1133]).
|
||||
|
||||
This setting can be configured via CLI flag `--http-rewrite`, and also in other ways:
|
||||
|
||||
* A builder option in `org.pkl.core.EvaluatorBuilder`
|
||||
* A builder option in `org.pkl.executor.ExecutorOptions`
|
||||
* A new property in `CreateEvaluatorRequest` in the Message Passing API
|
||||
* A new property in the Gradle plugin
|
||||
* A new property in `pkl.EvaluatorSettings#Http`
|
||||
|
||||
The main use-case for this setting is to enable package mirroring.
|
||||
For example, let's assume that the following mirrors exist:
|
||||
|
||||
|===
|
||||
|Original |Mirror
|
||||
|
||||
|\https://pkg.pkl-lang.org
|
||||
|\https://my.internal.mirror/pkg-pkl-lang
|
||||
|
||||
|\https://github.com
|
||||
|\https://my.internal.mirror/github
|
||||
|===
|
||||
|
||||
A user of the CLI can use these mirrors with the following settings.
|
||||
|
||||
.~/.pkl/settings.pkl
|
||||
[source,pkl]
|
||||
----
|
||||
amends "pkl:settings"
|
||||
|
||||
http {
|
||||
rewrites {
|
||||
["https://pkg.pkl-lang.org/"] = "https://my.internal.mirror/pkg-pkl-lang/"
|
||||
["https://github.com/"] = "https://my.internal.mirror/github/"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
To learn more about this feature, consult https://github.com/apple/pkl-evolution/blob/main/spices/SPICE-0016-http-rewrites.adoc[SPICE-0016].
|
||||
|
||||
== Noteworthy [small]#🎶#
|
||||
|
||||
Ready when you need them.
|
||||
|
||||
=== pkldoc, pkl-codegen-java, pkl-codegen-kotlin executables
|
||||
|
||||
The pkldoc, pkl-config-java and pkl-config-kotlin CLIs are published as their own executables (https://github.com/apple/pkl/pull/1023[#1023]).
|
||||
|
||||
Currently, these tools have excellent support when called from within the pkl-gradle plugin.
|
||||
However, the story for using these as CLIs is much clunkier.
|
||||
Users must call Java by including their published `.jar` files, as well as all of their dependencies via the `-classpath` argument.
|
||||
|
||||
In 0.29, they are all being published as executables.
|
||||
In particular, pkldoc is being published as both a Java executable and a native executable.
|
||||
On the other hand, pkl-codegen-java and pkl-codegen-kotlin are published as Java executables only.
|
||||
|
||||
For more information, see their download instructions:
|
||||
|
||||
* xref:pkl-doc:index.adoc#install-cli[pkldoc]
|
||||
* xref:java-binding:codegen.adoc#install-cli[pkl-codegen-java]
|
||||
* xref:kotlin-binding:codegen.adoc#install-cli[pkl-codegen-kotlin]
|
||||
|
||||
=== Java API changes
|
||||
|
||||
==== Resource Readers SPI added to preconfigured evaluators
|
||||
|
||||
A change was made to the preconfigured evaluators (https://github.com/apple/pkl/pull/1094[#1094]).
|
||||
|
||||
Currently, they add module key factories from service providers, but not resource readers.
|
||||
|
||||
This means that users of pkl-spring, for example, cannot add custom resource readers.
|
||||
This is also inconsistent (in the preconfigured evaluator, import can use custom schemes, but not read).
|
||||
|
||||
In Pkl 0.29, any resource reader registered via the Service Provider Interface will be added to the preconfigured evalutors.
|
||||
|
||||
==== New methods
|
||||
|
||||
New methods are introduced to the Java API.
|
||||
|
||||
* `org.pkl.core.Evaluator.evaluateOutputBytes`
|
||||
* `org.pkl.core.http.HttpClient.Builder.setRewrites`
|
||||
* `org.pkl.core.http.HttpClient.Builder.addRewrite`
|
||||
* `org.pkl.executor.ExecutorOptions.httpRewrites`
|
||||
* `org.pkl.config.java.ConfigEvaluatorBuilder.getHttpClient`
|
||||
* `org.pkl.config.java.ConfigEvaluatorBuilder.setHttpClient`
|
||||
|
||||
=== Standard Library changes
|
||||
|
||||
New properties, methods, classes and typealiases have been added to the standard library (https://github.com/apple/pkl/pull/1019[#1019], https://github.com/apple/pkl/pull/1053[#1053], https://github.com/apple/pkl/pull/1063[#1063], https://github.com/apple/pkl/pull/1144[#1144]).
|
||||
|
||||
==== Additions to `pkl:base`
|
||||
|
||||
* {uri-stdlib-String}#isBase64[`String.isBase64`]
|
||||
* {uri-stdlib-String}#base64DecodedBytes[`String.base64DecodedBytes`]
|
||||
* {uri-stdlib-String}#encodeToBytes()[`String.encodeToBytes()`]
|
||||
* {uri-stdlib-List}#mapNonNullIndexed()[`List.mapNonNullIndexed()`]
|
||||
* {uri-stdlib-List}#toBytes()[`List.toBytes()`]
|
||||
* {uri-stdlib-Set}#mapNonNullIndexed()[`Set.mapNonNullIndexed()`]
|
||||
* {uri-stdlib-FileOutput}#bytes[`FileOutput.bytes`]
|
||||
* {uri-stdlib-Resource}#bytes[`Resource.bytes`]
|
||||
* {uri-stdlib-Mapping}#getOrDefault()[`Mapping.getOrDefault()`]
|
||||
* {uri-stdlib-Listing}#getOrDefault()[`Listing.getOrDefault()`]
|
||||
* {uri-stdlib-baseModule}#Charset[`Charset`]
|
||||
* {uri-stdlib-Bytes}[`Bytes`]
|
||||
|
||||
==== Additions to `pkl:EvaluatorSettings`
|
||||
|
||||
* {uri-stdlib-evaluatorSettingsHttpClass}#rewrites[`Http.rewrites`]
|
||||
|
||||
==== Additions to `pkl:reflect`
|
||||
|
||||
* {uri-stdlib-reflectModule}#bytesType[`bytesType`]
|
||||
|
||||
=== `pkl` CLI changes
|
||||
|
||||
New features are added to the `pkl` CLI (https://github.com/apple/pkl/pull/1052[#1052], https://github.com/apple/pkl/pull/1056[#1056]).
|
||||
|
||||
==== Aggregated JUnit reports
|
||||
|
||||
A new set of CLI flags are introduced: `--junit-aggregate-reports`, and `--junit-aggregate-suite-name`.
|
||||
Collectively, these flags tell Pkl to combine the JUnit reports into a single file, instead of creating a file per Pkl module.
|
||||
|
||||
Thanks to https://github.com/gordonbondon[@gordonbondon] for contributing to this feature!
|
||||
|
||||
==== shell-completion subcommand
|
||||
|
||||
A new subcommand called `shell-completion` has been added to the Pkl CLI.
|
||||
|
||||
This command produces autocompletion scripts for a given shell.
|
||||
|
||||
The following example installs shell completions for https://fishshell.com[fish shell]:
|
||||
|
||||
[source,shellscript]
|
||||
----
|
||||
pkl shell-completion fish > "~/.config/fish/completions/pkl.fish"
|
||||
----
|
||||
|
||||
Thanks to https://github.com/gordonbondon[@gordonbondon] for contributing to this feature!
|
||||
|
||||
=== `@Generated` annotation for Java/Kotlin codegen
|
||||
|
||||
Classes generated by the Java and Kotlin code generator can optionally recieve new annotation called `Generated` (https://github.com/apple/pkl/pull/1075[#1075], https://github.com/apple/pkl/pull/1115[#1115]).
|
||||
|
||||
This behavior is toggled with the `--generated-annotation` CLI flag, or the similarly named Gradle property.
|
||||
|
||||
When enabled, classes are annotated with `org.pkl.config.java.Generated`.
|
||||
|
||||
This allows users of JaCoCo to exclude Pkl-generated classes from coverage reports.
|
||||
|
||||
Thanks to https://github.com/arouel[@arouel] for their contributions here!
|
||||
|
||||
== Breaking Changes [small]#💔#
|
||||
|
||||
Things to watch out for when upgrading.
|
||||
|
||||
=== Standard library deprecations
|
||||
|
||||
The following methods have been deprecated in the standard library:
|
||||
|
||||
|===
|
||||
|Method name |Details
|
||||
|
||||
|`Resource.md5`
|
||||
|Replaced with `Resource.bytes.md5`
|
||||
|
||||
|`Resource.sha1`
|
||||
|Replaced with `Resource.bytes.sha1`
|
||||
|
||||
|`Resource.sha256`
|
||||
|Replaced with `Resource.bytes.sha256`
|
||||
|
||||
|`Resource.sha256Int`
|
||||
|Replaced with `Resource.bytes.sha256Int`
|
||||
|===
|
||||
|
||||
=== Grammar changes
|
||||
|
||||
New rules have been introduced to the parser (https://github.com/apple/pkl/pull/1022[#1022], https://github.com/apple/pkl/pull/1126[#1126]).
|
||||
|
||||
==== Block comment nesting is removed
|
||||
|
||||
Currently, block comments can be nested.
|
||||
For example, the comment `/* /* my comment */ */` is two block comments; one outer comment and one inner comment.
|
||||
|
||||
However, this has some drawbacks.
|
||||
|
||||
1. Block comments can be possibly be closed incorrectly, like `/* /* my comment */`. However, this is a valid block comment in most languages.
|
||||
2. Pkl's syntax highlighters do not support block comment nesting, leading to highlighting that is inconsistent with Pkl's parser.
|
||||
|
||||
To improve user experience, block comment nesting is removed.
|
||||
As a result, block comments are always terminated upon the first `*/`.
|
||||
|
||||
==== Shebang line can only appear at the start of a file
|
||||
|
||||
The grammar around shebang comments has been made stricter.
|
||||
|
||||
Pkl files allow for a https://en.wikipedia.org/wiki/Shebang_(Unix)[shebang comment].
|
||||
Currently, this comment can appear anywhere in a file.
|
||||
In 0.29, this comment must appear at the start of a file.
|
||||
|
||||
=== Opaque `file:` URIs are invalid
|
||||
|
||||
A new rule is introduced to treat opaque `file:` URIs as errors (https://github.com/apple/pkl/pull/1087[#1087]).
|
||||
|
||||
Opaque file URIs are URIs whose scheme-specific part does not start with `/`.
|
||||
For example, `file:foo/bar.txt` is an opaque URI.
|
||||
|
||||
Currently, this has the unintentional behavior of: look for file `foo/bar.txt` from the process working directory.
|
||||
These are effectively dynamics imports; from a single import, we can't statically determine what file is actually being imported.
|
||||
|
||||
According to https://datatracker.ietf.org/doc/html/rfc8089#section-2[RFC-8089], `file` URIs must have paths that start with /.
|
||||
So, these are actually not valid URIs.
|
||||
|
||||
In Pkl 0.29, it is an error to load a module or resource with an opaque `file:` URI.
|
||||
|
||||
NOTE: To import or read a relative path, omit `file:` from the import string. For example, `import("foo/bar.txt")` instead of `import("file:foo/bar.txt")`.
|
||||
|
||||
=== New base module names: `Bytes` and `Charset`
|
||||
|
||||
Two new names are introduced to the base module: `Bytes` and `Charset`.
|
||||
That means that any code that currently references these names on implicit `this` will break (https://github.com/apple/pkl/pull/1019[#1019]).
|
||||
|
||||
The following snippet demonstrates this breaking behavior.
|
||||
In 0.28 and below, `obj2.prop` resolves to string "my bytes".
|
||||
In 0.29, it resolves to class `Bytes` in the base module.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
obj1 {
|
||||
Bytes = "my bytes"
|
||||
}
|
||||
|
||||
obj2 = (obj1) {
|
||||
prop = Bytes
|
||||
}
|
||||
----
|
||||
|
||||
To make this code continue to have the same meaning, an explicit `this` reference is required.
|
||||
|
||||
[source,diff]
|
||||
----
|
||||
obj1 {
|
||||
Bytes = "my bytes"
|
||||
}
|
||||
|
||||
obj2 = (obj1) {
|
||||
- prop = Bytes
|
||||
+ prop = this.Bytes
|
||||
}
|
||||
----
|
||||
|
||||
This only affects code that references these names off of implicit this.
|
||||
Code that references the name from the lexical scope will continue to work as-is.
|
||||
|
||||
To learn more about name resolution, consult the xref:language-reference:index.adoc#name-resolution[language reference].
|
||||
|
||||
=== jpkl is not published to Maven Central
|
||||
|
||||
Due to a breakage in release pipeline, the `jpkl` executable is not published to Maven Central (https://github.com/apple/pkl/pull/1147[#1147]).
|
||||
|
||||
It is still available to download as a GitHub release asset.
|
||||
|
||||
== Miscellaneous [small]#🐸#
|
||||
|
||||
* Documentation improvements (https://github.com/apple/pkl/pull/1065[#1065], https://github.com/apple/pkl/pull/1127[#1127]).
|
||||
* Dependency updates (https://github.com/apple/pkl/pull/1088[#1088], https://github.com/apple/pkl/pull/1128[#1128], https://github.com/apple/pkl/pull/1139[#1139]).
|
||||
* Use `javac -release` and `kotlinc -Xjdk-release` compiler flags for improved bytecode compatibilty (https://github.com/apple/pkl/pull/1080[#1080]).
|
||||
* Parser improvements (https://github.com/apple/pkl/pull/1066[#1066]).
|
||||
|
||||
== Bugs fixed [small]#🐜#
|
||||
|
||||
The following bugs have been fixed.
|
||||
|
||||
* New parser fails on nested multi line comments (https://github.com/apple/pkl/issues/1014[#1014])
|
||||
* Fix package dependency links when generating pkldoc (https://github.com/apple/pkl/pull/1078[#1078])
|
||||
* Don't show 100% when number of failures is rounded up (https://github.com/apple/pkl/pull/1110[#1110])
|
||||
* Quoting the module name crashes pkl (https://github.com/apple/pkl/issues/1111[#1111])
|
||||
* Shebang comment parsing is too lenient (https://github.com/apple/pkl/issues/1125[#1125])
|
||||
* CLI: noProxy option in settings.pkl and PklProject are ignored (https://github.com/apple/pkl/issues/1142[#1142])
|
||||
|
||||
== Contributors [small]#🙏#
|
||||
|
||||
We would like to thank the contributors to this release (in alphabetical order):
|
||||
|
||||
* https://github.com/arouel[@arouel]
|
||||
* https://github.com/gordonbondon[@gordonbondon]
|
||||
* https://github.com/HT154[@HT154]
|
||||
* https://github.com/KushalP[@KushalP]
|
||||
* https://github.com/madrob[@madrob]
|
||||
* https://github.com/MikeSchulze[@MikeSchulze]
|
||||
* https://github.com/sitaktif[@sitaktif]
|
||||
* https://github.com/vlsi[@vlsi]
|
||||
@@ -1,6 +1,153 @@
|
||||
= Changelog
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
|
||||
[[release-0.29.1]]
|
||||
== 0.29.1 (2025-08-27)
|
||||
|
||||
=== Fixes
|
||||
|
||||
* Fixes an issue where autocompletion in Bash and ZSH do noes not suggest filenames (https://github.com/apple/pkl/pull/1161[#1161]).
|
||||
* Fixes an issue where `pkldoc` throws a runtime error about failing to load class path resources (https://github.com/apple/pkl/issues/1174[#1174]).
|
||||
* Fixes an issue where `pkldoc` always runs with `testMode` set to true.
|
||||
* Fixes an issue where evaluating a module that ends with an unmatched backtick throws `ArrayIndexOutOfBoundsException` (https://github.com/apple/pkl/issues/1182[#1182]).
|
||||
* Fixes the formatting of YAML strings when emitting backslash characters within quoted strings (https://github.com/apple/pkl/pull/1165[#1165]).
|
||||
* Fixes an issue where `local` members inside `Mapping` objects are incorrectly encoded into binary format (https://github.com/apple/pkl/issues/1151[#1151]).
|
||||
|
||||
=== Contributors ❤️
|
||||
|
||||
Thank you to all the contributors for this release!
|
||||
|
||||
* https://github.com/bioball[@bioball]
|
||||
* https://github.com/gordonbondon[@gordonbondon]
|
||||
* https://github.com/HT154[@HT154]
|
||||
|
||||
[[release-0.29.0]]
|
||||
== 0.29.0 (2025-07-24)
|
||||
|
||||
xref:0.29.adoc[Release notes]
|
||||
|
||||
[[release-0.28.2]]
|
||||
== 0.28.2 (2025-04-17)
|
||||
|
||||
=== Fixes
|
||||
|
||||
* Adds an optimization when object bodies with generators produce no members (https://github.com/apple/pkl/pull/1013[#1013]).
|
||||
* Fixes a runtime crash when `--output-path` points to a directory (https://github.com/apple/pkl/pull/1038[#1038]).
|
||||
* Fixes a bug that sometimes causes pkl-doc to crash (https://github.com/apple/pkl/pull/1028[#1028]).
|
||||
|
||||
=== Miscellaneous
|
||||
|
||||
* Documentation improvements (https://github.com/apple/pkl/pull/982[#982], https://github.com/apple/pkl/pull/1010[#1010], https://github.com/apple/pkl/pull/1031[#1031]).
|
||||
* CI improvements (https://github.com/apple/pkl/pull/1020[#1020]).
|
||||
|
||||
=== Contributors ❤️
|
||||
|
||||
Thank you to all the contributors for this release!
|
||||
|
||||
* https://github.com/JeroenSoeters[@JeroenSoeters]
|
||||
* https://github.com/KushalP[@KushalP]
|
||||
* https://github.com/mbvissers[@mbvissers]
|
||||
* https://github.com/pepicrft[@pepicrft]
|
||||
|
||||
[[release-0.28.1]]
|
||||
== 0.28.1 (2025-03-03)
|
||||
|
||||
=== Fixes
|
||||
|
||||
* Fixes an issue where Pkl Gradle tasks can possibly fail with `java.lang.UnsatisfiedLinkError` (https://github.com/apple/pkl/pull/995[#995]).
|
||||
* Fixes an issue where the artifacts pkl-tools and pkl-config-java-all fail with `java.lang.ClassFormatError` (https://github.com/apple/pkl/pull/998[#998]).
|
||||
|
||||
=== Changes
|
||||
|
||||
* Adds the ability to configure `native-image` build with Gradle system properties (https://github.com/apple/pkl/pull/1001[#1001]).
|
||||
+
|
||||
Now, any system property starting with `"pkl.native"` will have that prefix stripped, and the rest passed as CLI arguments to `native-image`. For example, the native-image resource cache can be configured by passing Gradle flag `-Dpkl.native-Dpolyglot.engine.userResourceCache=/my/cache/dir`.
|
||||
|
||||
[[release-0.28.0]]
|
||||
== 0.28.0 (2025-02-26)
|
||||
|
||||
xref:0.28.adoc[Release notes]
|
||||
|
||||
[[release-0.27.2]]
|
||||
== 0.27.2 (2025-01-22)
|
||||
|
||||
=== Fixes
|
||||
|
||||
* Fixes issues where server mode message decoding might result in null pointer exceptions (https://github.com/apple/pkl/pull/853[#853], https://github.com/apple/pkl/pull/882[#882]).
|
||||
* Fixes an issue where the test report outputs decimal numbers using local-specific decimals (https://github.com/apple/pkl/pull/868[#868]).
|
||||
* Fixes an issue where the native executables might not run on some environments, resulting in an error like "Fatal error: Failed to create the main Isolate" (https://github.com/apple/pkl/pull/875[#875]).
|
||||
|
||||
=== Contributors ❤️
|
||||
|
||||
Thank you to all the contributors for this release!
|
||||
|
||||
* link:https://github.com/HT154[@HT154]
|
||||
* link:https://github.com/StefMa[@StefMa]
|
||||
|
||||
[[release-0.27.1]]
|
||||
== 0.27.1 (2024-12-06)
|
||||
|
||||
=== Fixes
|
||||
|
||||
- Fixes a broken "number literals" link in the 0.27 release notes (https://github.com/apple/pkl/pull/784[#784]).
|
||||
- Fixes a possible deadlock during external reader process close (https://github.com/apple/pkl/pull/786[#786]).
|
||||
- Fixes counting elements with computed indices multiple times in length computation of listings (https://github.com/apple/pkl/pull/797[#797]).
|
||||
- Fixes non Pkl modules being reported in GatherImports task, leading to plugin failures (https://github.com/apple/pkl/pull/821[#821]).
|
||||
- Fixes a problem where the delegate chain of type casts for Listing/Mapping get unreasonably big, even though the type nodes are the same, which may lead to a stack overflow or performance degradation (https://github.com/apple/pkl/pull/826[#826]).
|
||||
- Fixes incorrect scoping of type variables in lazy Listing/Mapping type checking in cross-module typealiases (https://github.com/apple/pkl/pull/789[#789]).
|
||||
- Fixes regression in type checking logic for Listing/Mapping (https://github.com/apple/pkl/pull/789[#789]).
|
||||
|
||||
=== Contributors ❤️
|
||||
|
||||
Thank you to all the contributors for this release!
|
||||
|
||||
* link:https://github.com/GUI[@GUI]
|
||||
* link:https://github.com/HT154[@HT154]
|
||||
* link:https://github.com/odenix[@odenix] (formerly @translatenix)
|
||||
|
||||
|
||||
[[release-0.27.0]]
|
||||
== 0.27.0 (2024-11-05)
|
||||
|
||||
xref:0.27.adoc[Release notes]
|
||||
|
||||
[[release-0.26.3]]
|
||||
== 0.26.3 (2024-08-06)
|
||||
|
||||
=== Fixes
|
||||
|
||||
* Fixes an issue where CLI argument `--property foo=""` is effectively parsed as `--property foo="true"`. This is now parsed as an empty string (https://github.com/apple/pkl/pull/596[#596]).
|
||||
* Fixes a regression where amending a globbed import or globbed read results in a PklBugException (https://github.com/apple/pkl/pull/607[#607]).
|
||||
* Fixes an issue around using `file()` notation when using the pkl-gradle plugin on Windows (https://github.com/apple/pkl/pull/611[#611]).
|
||||
|
||||
[[release-0.26.2]]
|
||||
== 0.26.2 (2024-07-18)
|
||||
|
||||
=== Fixes
|
||||
|
||||
* Fixes a possible race condition where multiple concurrent Pkl evaluations results in a thrown exception when downloading packages (https://github.com/apple/pkl/pull/584[#584]).
|
||||
|
||||
[[release-0.26.1]]
|
||||
== 0.26.1 (2024-06-28)
|
||||
|
||||
=== Fixes
|
||||
|
||||
* Fixes a regression where native executables fail to run on some environments that don't support newer CPU features (https://github.com/apple/pkl/pull/551[#551]).
|
||||
* Fixes a `PklBugException` when passing `.` as a project directory to `pkl project resolve` and `pkl project package` (https://github.com/apple/pkl/pull/544[#544]).
|
||||
|
||||
=== Changes
|
||||
|
||||
* Disable revocation checking of TLS certificates (https://github.com/apple/pkl/pull/553[#553]).
|
||||
+
|
||||
As part of HTTP improvements in 0.26, we unwittingly fixed a bug where Pkl does not actually perform cert revocation checks when making HTTPS requests.
|
||||
This fix, unfortunately, caused a regression in some cases.
|
||||
For example, this happens when connecting to a server that bears a public trust certificate, while in an environment with no internet access.
|
||||
This is because the HTTP client needs to check the revocation status of all certificates in the chain.
|
||||
+
|
||||
Revocation checks are a nuanced topic with some benefits, and also with its own problem areas.
|
||||
For this reason, revocation checking is disabled for Pkl's native CLIs.
|
||||
Users of Pkl's Java APIs will respect the revocation settings set in the JVM.
|
||||
|
||||
[[release-0.26.0]]
|
||||
== 0.26.0 (2024-06-17)
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
= Release Notes
|
||||
|
||||
The Pkl team aims to release a new version of Pkl in February, June, and October of each year.
|
||||
|
||||
* xref:0.29.adoc[0.29 Release Notes]
|
||||
* xref:0.28.adoc[0.28 Release Notes]
|
||||
* xref:0.27.adoc[0.27 Release Notes]
|
||||
* xref:0.26.adoc[0.26 Release Notes]
|
||||
* xref:0.25.adoc[0.25 Release Notes]
|
||||
* xref:changelog.adoc[Changelog]
|
||||
|
||||
@@ -12,7 +12,7 @@ XXX
|
||||
|
||||
The next release (XXX) is scheduled for XXX (e.g., August 2, 2021).
|
||||
|
||||
Please send feedback and questions to https://github.com/apple/pkl/discussions[GitHub Discussions], or submit an issue on https://github.com/apple/pkl/issues/new[Github]. +
|
||||
Please send feedback and questions to https://github.com/apple/pkl/discussions[GitHub Discussions], or submit an issue on https://github.com/apple/pkl/issues/new[GitHub]. +
|
||||
|
||||
[small]#Pkl is hosted on https://github.com/apple/pkl[GitHub].
|
||||
To get started, follow xref:pkl-cli:index.adoc#installation[Installation].#
|
||||
|
||||
@@ -356,7 +356,7 @@ myString = #"foo \ bar \ baz"#
|
||||
myString = "foo \\ bar \\ baz"
|
||||
----
|
||||
|
||||
NOTE: Sometimes, using custom string delimiters makes source code harder to read. For example, the `+\#+` literal reads better using escapes (`"\\#"`) than using custom string delimimters (`+##"\#"##+`).
|
||||
NOTE: Sometimes, using custom string delimiters makes source code harder to read. For example, the `+\#+` literal reads better using escapes (`"\\#"`) than using custom string delimiters (`+##"\#"##+`).
|
||||
|
||||
=== Interpolation
|
||||
|
||||
|
||||
@@ -38,7 +38,12 @@
|
||||
|
||||
* xref:ROOT:examples.adoc[Examples]
|
||||
|
||||
* xref:ROOT:evolution-and-roadmap.adoc[Evolution and Roadmap]
|
||||
|
||||
* xref:release-notes:index.adoc[Release Notes]
|
||||
** xref:release-notes:0.29.adoc[0.29 Release Notes]
|
||||
** xref:release-notes:0.28.adoc[0.28 Release Notes]
|
||||
** xref:release-notes:0.27.adoc[0.27 Release Notes]
|
||||
** xref:release-notes:0.26.adoc[0.26 Release Notes]
|
||||
** xref:release-notes:0.25.adoc[0.25 Release Notes]
|
||||
** xref:release-notes:changelog.adoc[Changelog]
|
||||
|
||||
@@ -16,16 +16,15 @@ import org.pkl.core.Loggers
|
||||
import org.pkl.core.SecurityManagers
|
||||
import org.pkl.core.StackFrameTransformers
|
||||
import org.pkl.core.module.ModuleKeyFactories
|
||||
import org.pkl.core.parser.LexParseException
|
||||
import org.pkl.core.parser.Parser
|
||||
import org.pkl.core.parser.antlr.PklParser
|
||||
import org.pkl.core.repl.ReplRequest
|
||||
import org.pkl.core.repl.ReplResponse
|
||||
import org.pkl.core.repl.ReplServer
|
||||
import org.pkl.core.resource.ResourceReaders
|
||||
import org.pkl.core.util.IoUtils
|
||||
import org.antlr.v4.runtime.ParserRuleContext
|
||||
import org.pkl.core.http.HttpClient
|
||||
import org.pkl.parser.Parser
|
||||
import org.pkl.parser.ParserError
|
||||
import org.pkl.parser.syntax.ClassProperty
|
||||
import org.pkl.core.resource.ResourceReaders
|
||||
import java.nio.file.Files
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.io.path.isRegularFile
|
||||
@@ -38,10 +37,10 @@ class DocSnippetTestsEngine : HierarchicalTestEngine<DocSnippetTestsEngine.Execu
|
||||
private val projectDir = rootProjectDir.resolve("docs")
|
||||
private val docsDir = projectDir.resolve("modules")
|
||||
|
||||
companion object {
|
||||
private companion object {
|
||||
val headingRegex = Regex("""(?u)^\s*(=++)\s*(.+)""")
|
||||
val collapsibleBlockRegex = Regex("""(?u)^\s*\[%collapsible""")
|
||||
val codeBlockRegex = Regex("""(?u)^\s*\[source(?:%(tested|parsed)(%error)?)?(?:,(?:\{)?([a-zA-Z-_]+)}?)?""")
|
||||
val codeBlockRegex = Regex("""(?u)^\s*\[source(?:%(tested|parsed)(%error)?)?(?:,\{?([a-zA-Z-_]+)}?)?""")
|
||||
val codeBlockNameRegex = Regex("""(?u)^\s*\.(.+)""")
|
||||
val codeBlockDelimiterRegex = Regex("""(?u)^\s*----""")
|
||||
val graphicsRegex = Regex("\\[small]#.+#")
|
||||
@@ -96,7 +95,8 @@ class DocSnippetTestsEngine : HierarchicalTestEngine<DocSnippetTestsEngine.Execu
|
||||
null,
|
||||
null,
|
||||
IoUtils.getCurrentWorkingDir(),
|
||||
StackFrameTransformers.defaultTransformer
|
||||
StackFrameTransformers.defaultTransformer,
|
||||
false,
|
||||
)
|
||||
return ExecutionContext(replServer)
|
||||
}
|
||||
@@ -149,6 +149,7 @@ class DocSnippetTestsEngine : HierarchicalTestEngine<DocSnippetTestsEngine.Execu
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
private fun parseAsciidoc(docDescriptor: Descriptor.Path, selectors: List<UniqueIdSelector>) {
|
||||
var line = ""
|
||||
var prevLine = ""
|
||||
@@ -301,7 +302,7 @@ class DocSnippetTestsEngine : HierarchicalTestEngine<DocSnippetTestsEngine.Execu
|
||||
|
||||
override fun getType() = Type.TEST
|
||||
|
||||
private val parsed: ParserRuleContext by lazy {
|
||||
private val parsed: org.pkl.parser.syntax.Node by lazy {
|
||||
when (language) {
|
||||
"pkl" -> Parser().parseModule(code)
|
||||
"pkl-expr" -> Parser().parseExpressionInput(code)
|
||||
@@ -316,7 +317,7 @@ class DocSnippetTestsEngine : HierarchicalTestEngine<DocSnippetTestsEngine.Execu
|
||||
if (expectError) {
|
||||
throw AssertionError("Expected a parse error, but got none.")
|
||||
}
|
||||
} catch (e: LexParseException) {
|
||||
} catch (e: ParserError) {
|
||||
if (!expectError) {
|
||||
throw AssertionError(e.message)
|
||||
}
|
||||
@@ -333,7 +334,7 @@ class DocSnippetTestsEngine : HierarchicalTestEngine<DocSnippetTestsEngine.Execu
|
||||
)
|
||||
)
|
||||
|
||||
val properties = parsed.children.filterIsInstance<PklParser.ClassPropertyContext>()
|
||||
val properties = parsed.children()?.filterIsInstance<ClassProperty>() ?: emptyList()
|
||||
|
||||
val responses = mutableListOf<ReplResponse>()
|
||||
|
||||
@@ -342,7 +343,7 @@ class DocSnippetTestsEngine : HierarchicalTestEngine<DocSnippetTestsEngine.Execu
|
||||
responses.addAll(context.replServer.handleRequest(
|
||||
ReplRequest.Eval(
|
||||
"snippet",
|
||||
prop.Identifier().text,
|
||||
prop.name.value,
|
||||
false,
|
||||
true
|
||||
)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# suppress inspection "UnusedProperty" for whole file
|
||||
|
||||
group=org.pkl-lang
|
||||
version=0.26.0
|
||||
version=0.29.1
|
||||
|
||||
# google-java-format requires jdk.compiler exports
|
||||
org.gradle.jvmargs= \
|
||||
-XX:+UseParallelGC \
|
||||
-Dfile.encoding=UTF-8 \
|
||||
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
|
||||
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
|
||||
@@ -15,4 +16,5 @@ org.gradle.jvmargs= \
|
||||
org.gradle.parallel=true
|
||||
org.gradle.caching=true
|
||||
kotlin.stdlib.default.dependency=false
|
||||
kotlin.daemon.jvmargs=-XX:+UseParallelGC
|
||||
#org.gradle.workers.max=1
|
||||
|
||||
@@ -1,59 +1,57 @@
|
||||
[versions] # ordered alphabetically
|
||||
antlr = "4.+"
|
||||
assertj = "3.+"
|
||||
checksumPlugin = "1.2.0"
|
||||
clikt = "3.5.1"
|
||||
assertj = "3.+"
|
||||
checksumPlugin = "1.4.0"
|
||||
clikt = "5.+"
|
||||
commonMark = "0.+"
|
||||
downloadTaskPlugin = "5.6.0"
|
||||
geantyref = "1.+"
|
||||
googleJavaFormat = "1.21.0"
|
||||
googleJavaFormat = "1.25.2"
|
||||
# must not use `+` because used in download URL
|
||||
graalVm = "23.0.2"
|
||||
graalVmJdkVersion = "17.0.10"
|
||||
# 23.1.x requires JDK 20+
|
||||
graalVm = "24.1.2"
|
||||
graalVmJdkVersion = "21.0.8"
|
||||
# slightly hacky but convenient place so we remember to update the checksum
|
||||
graalVmSha256-macos-x64 = "14f4bd6417809905f86e786c779d0fc2feb840d7dac35ae3503eb25af0530da0"
|
||||
graalVmSha256-macos-aarch64 = "e944c5ce5da56e683fc8f1a57191b46d9cb702930b1688bda064fcf467d876b8"
|
||||
graalVmSha256-linux-x64 = "112dc9b92d81a946f1b5b334646151b790785c813e76fcf13527a319003d7e2c"
|
||||
graalVmSha256-linux-aarch64 = "c95ac550d070f06666cf8c1023a098380dd565be00866473caf6ff1b7cdf680c"
|
||||
graalVmSha256-windows-x64 = "1ab2291e71f54d73e3e57b7fccbf184cabcba37e16ca9d1cf42d08474a7c02f0"
|
||||
ideaExtPlugin = "1.1"
|
||||
javaPoet = "1.+"
|
||||
graalVmSha256-macos-x64 = "1a63681c9042f92f27da535c3b0fada62aae094da1f705ecb0ef0270b80f873b"
|
||||
graalVmSha256-macos-aarch64 = "3de4049d254dd3c04fd65a66be904d6cf490dca4ece2e2b5fcdfa91d34760f4f"
|
||||
graalVmSha256-linux-x64 = "c8035b3ce6e45f1481752c6b38153bb4a53eeb477c5345d5bec5ca44ed18a056"
|
||||
graalVmSha256-linux-aarch64 = "aa1100beb3377717a0ba1937e51878c48917615922a36c4508baf46927a9a6e4"
|
||||
graalVmSha256-windows-x64 = "0401a5c9b4a5478640b0d5563a5e0f2c97513ab689c5ee647d41293b92eed0e4"
|
||||
ideaExtPlugin = "1.1.9"
|
||||
javaPoet = "0.+"
|
||||
javaxInject = "1"
|
||||
jansi = "2.+"
|
||||
jimfs = "1.+"
|
||||
# 3.25.1 doesn't work with native image
|
||||
# later versions don't work with native image
|
||||
# (at least not without additional configuration; tested with 3.25.1 and 3.27.1)
|
||||
jline = "3.23.0"
|
||||
jmh = "1.+"
|
||||
jmhPlugin = "0.6.6"
|
||||
jmhPlugin = "0.7.2"
|
||||
jsr305 = "3.+"
|
||||
junit = "5.+"
|
||||
kotlin = "1.7.10"
|
||||
junitPlatform = "1.+"
|
||||
kotlin = "2.0.21"
|
||||
# 1.7+ generates much more verbose code
|
||||
kotlinPoet = "1.6.+"
|
||||
# freeze until updating Kotlin version
|
||||
kotlinxHtml = "0.8.1"
|
||||
# freeze until updating Kotlin version
|
||||
kotlinxSerialization = "1.5.1"
|
||||
ktfmt = "0.44"
|
||||
kotlinxHtml = "0.11.0"
|
||||
kotlinxSerialization = "1.8.0"
|
||||
ktfmt = "0.53"
|
||||
# replaces nuValidator's log4j dependency
|
||||
# something related to log4j-1.2-api is apparently broken in 2.17.2
|
||||
log4j = "2.17.1"
|
||||
msgpack = "0.9.0"
|
||||
nexusPublishPlugin = "1.3.0"
|
||||
msgpack = "0.9.8"
|
||||
nexusPublishPlugin = "2.0.0"
|
||||
nuValidator = "20.+"
|
||||
paguro = "3.+"
|
||||
shadowPlugin = "8.1.1"
|
||||
slf4j = "1.+"
|
||||
# Breaking change in snakeYaml 2.6 (removing DumpSettingsBuilder::setScalarResolver), so pin to 2.5
|
||||
snakeYaml = "2.5"
|
||||
spotlessPlugin = "6.11.0"
|
||||
snakeYaml = "2.+"
|
||||
spotlessPlugin = "6.25.0"
|
||||
wiremock = "3.+"
|
||||
|
||||
[libraries] # ordered alphabetically
|
||||
antlr = { group = "com.tunnelvisionlabs", name = "antlr4", version.ref = "antlr" }
|
||||
antlrRuntime = { group = "com.tunnelvisionlabs", name = "antlr4-runtime", version.ref = "antlr" }
|
||||
assertj = { group = "org.assertj", name = "assertj-core", version.ref = "assertj" }
|
||||
clikt = { group = "com.github.ajalt.clikt", name = "clikt", version.ref = "clikt" }
|
||||
cliktMarkdown = { group = "com.github.ajalt.clikt", name = "clikt-markdown", version.ref = "clikt" }
|
||||
commonMark = { group = "org.commonmark", name = "commonmark", version.ref = "commonMark" }
|
||||
commonMarkTables = { group = "org.commonmark", name = "commonmark-ext-gfm-tables", version.ref = "commonMark" }
|
||||
downloadTaskPlugin = { group = "de.undercouch", name = "gradle-download-task", version.ref = "downloadTaskPlugin" }
|
||||
@@ -61,7 +59,7 @@ geantyref = { group = "io.leangen.geantyref", name = "geantyref", version.ref =
|
||||
graalCompiler = { group = "org.graalvm.compiler", name = "compiler", version.ref = "graalVm" }
|
||||
graalSdk = { group = "org.graalvm.sdk", name = "graal-sdk", version.ref = "graalVm" }
|
||||
graalJs = { group = "org.graalvm.js", name = "js", version.ref = "graalVm" }
|
||||
javaPoet = { group = "com.squareup", name = "javapoet", version.ref = "javaPoet" }
|
||||
javaPoet = { group = "com.palantir.javapoet", name = "javapoet", version.ref = "javaPoet" }
|
||||
javaxInject = { group = "javax.inject", name = "javax.inject", version.ref = "javaxInject" }
|
||||
jansi = { group = "org.fusesource.jansi", name = "jansi", version.ref = "jansi" }
|
||||
jimfs = { group = "com.google.jimfs", name = "jimfs", version.ref = "jimfs" }
|
||||
@@ -72,12 +70,12 @@ jsr305 = { group = "com.google.code.findbugs", name = "jsr305", version.ref = "j
|
||||
junitApi = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit" }
|
||||
junitEngine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", version.ref = "junit" }
|
||||
junitParams = { group = "org.junit.jupiter", name = "junit-jupiter-params", version.ref = "junit" }
|
||||
junitLauncher = { group = "org.junit.platform", name = "junit-platform-launcher", version.ref = "junitPlatform" }
|
||||
kotlinCompilerEmbeddable = { group = "org.jetbrains.kotlin", name = "kotlin-compiler-embeddable", version.ref = "kotlin" }
|
||||
kotlinPlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
|
||||
kotlinPoet = { group = "com.squareup", name = "kotlinpoet", version.ref = "kotlinPoet" }
|
||||
kotlinReflect = { group = "org.jetbrains.kotlin", name = "kotlin-reflect", version.ref = "kotlin" }
|
||||
kotlinScriptingCompilerEmbeddable = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-compiler-embeddable", version.ref = "kotlin" }
|
||||
kotlinScriptUtil = { group = "org.jetbrains.kotlin", name = "kotlin-script-util", version.ref = "kotlin" }
|
||||
kotlinScripting = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-jsr223", version.ref = "kotlin" }
|
||||
kotlinStdLib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk8", version.ref = "kotlin" }
|
||||
kotlinxHtml = { group = "org.jetbrains.kotlinx", name = "kotlinx-html-jvm", version.ref = "kotlinxHtml" }
|
||||
kotlinxSerializationJson = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerialization" }
|
||||
@@ -95,6 +93,8 @@ spotlessPlugin = { group = "com.diffplug.spotless", name = "spotless-plugin-grad
|
||||
svm = { group = "org.graalvm.nativeimage", name = "svm", version.ref = "graalVm" }
|
||||
truffleApi = { group = "org.graalvm.truffle", name = "truffle-api", version.ref = "graalVm" }
|
||||
truffleDslProcessor = { group = "org.graalvm.truffle", name = "truffle-dsl-processor", version.ref = "graalVm" }
|
||||
truffleSvm = { group = "org.graalvm.nativeimage", name = "truffle-runtime-svm", version.ref = "graalVm" }
|
||||
truffleRuntime = { group = "org.graalvm.truffle", name = "truffle-runtime", version.ref = "graalVm" }
|
||||
wiremock = { group = "org.wiremock", name = "wiremock", version.ref = "wiremock" }
|
||||
|
||||
[plugins] # ordered alphabetically
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,7 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
distributionSha256Sum=bd71102213493060956ec229d946beee57158dbd89d0e62b91bca0fa2c5f3531
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
12
gradlew
vendored
12
gradlew
vendored
@@ -15,6 +15,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
@@ -55,7 +57,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -84,7 +86,7 @@ done
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@@ -112,7 +114,7 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -203,7 +205,7 @@ fi
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
@@ -211,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
|
||||
6
gradlew.bat
vendored
6
gradlew.bat
vendored
@@ -13,6 +13,8 @@
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@@ -68,11 +70,11 @@ goto fail
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
18
jbang-catalog.json
Normal file
18
jbang-catalog.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"catalogs": {},
|
||||
"aliases": {
|
||||
"pkl": {
|
||||
"script-ref": "org.pkl-lang:pkl-cli-java:0.29.1",
|
||||
"java-agents": []
|
||||
},
|
||||
"pkl-codegen-java": {
|
||||
"script-ref": "org.pkl-lang:pkl-codegen-java:0.29.1",
|
||||
"java-agents": []
|
||||
},
|
||||
"pkl-codegen-kotlin": {
|
||||
"script-ref": "org.pkl-lang:pkl-codegen-kotlin:0.29.1",
|
||||
"java-agents": []
|
||||
}
|
||||
},
|
||||
"templates": {}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
# This is a Gradle generated file for dependency locking.
|
||||
# Manual edits can break the build and are not advised.
|
||||
# This file is expected to be part of source control.
|
||||
net.bytebuddy:byte-buddy:1.14.16=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
|
||||
org.assertj:assertj-core:3.26.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.7.10=kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains:annotations:13.0=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.jupiter:junit-jupiter-engine:5.10.2=testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.jupiter:junit-jupiter-params:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.platform:junit-platform-engine:1.10.2=testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit:junit-bom:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
empty=annotationProcessor,apiDependenciesMetadata,compileClasspath,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtimeClasspath,runtimeOnlyDependenciesMetadata,signatures,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDef,testKotlinScriptDefExtensions
|
||||
@@ -1,104 +1,130 @@
|
||||
# This is a Gradle generated file for dependency locking.
|
||||
# Manual edits can break the build and are not advised.
|
||||
# This file is expected to be part of source control.
|
||||
com.ethlo.time:itu:1.8.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-annotations:2.17.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-core:2.17.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-databind:2.17.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.17.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson:jackson-bom:2.17.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.github.ajalt.clikt:clikt-jvm:3.5.1=compileClasspath,default,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.clikt:clikt:3.5.1=apiDependenciesMetadata,compileClasspath,default,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.ethlo.time:itu:1.10.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-annotations:2.19.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-core:2.19.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-databind:2.19.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.19.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.19.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson:jackson-bom:2.19.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.github.ajalt.clikt:clikt-core-jvm:5.0.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.clikt:clikt-core:5.0.3=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.github.ajalt.clikt:clikt-jvm:5.0.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.clikt:clikt-markdown-jvm:5.0.3=runtimeClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.clikt:clikt-markdown:5.0.3=runtimeClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.clikt:clikt:5.0.3=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.github.ajalt.colormath:colormath-jvm:3.6.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.colormath:colormath:3.6.0=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.github.ajalt.mordant:mordant-core-jvm:3.0.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.mordant:mordant-core:3.0.1=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.github.ajalt.mordant:mordant-jvm-ffm-jvm:3.0.1=runtimeClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.mordant:mordant-jvm-ffm:3.0.1=runtimeClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.mordant:mordant-jvm-graal-ffi-jvm:3.0.1=runtimeClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.mordant:mordant-jvm-graal-ffi:3.0.1=runtimeClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.mordant:mordant-jvm-jna-jvm:3.0.1=runtimeClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.mordant:mordant-jvm-jna:3.0.1=runtimeClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.mordant:mordant-jvm:3.0.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.mordant:mordant-markdown-jvm:3.0.1=runtimeClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.mordant:mordant-markdown:3.0.1=runtimeClasspath,testRuntimeClasspath
|
||||
com.github.ajalt.mordant:mordant:3.0.1=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.github.jknack:handlebars-helpers:4.3.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.github.jknack:handlebars:4.3.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.26.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.google.guava:failureaccess:1.0.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.google.guava:guava:33.2.0-jre=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.36.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.google.guava:failureaccess:1.0.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.google.guava:guava:33.4.8-jre=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.google.j2objc:j2objc-annotations:3.0.0=testCompileClasspath,testImplementationDependenciesMetadata
|
||||
com.google.j2objc:j2objc-annotations:3.0.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.networknt:json-schema-validator:1.4.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.tunnelvisionlabs:antlr4-runtime:4.9.0=default,runtimeClasspath,testRuntimeClasspath
|
||||
commons-fileupload:commons-fileupload:1.5=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
commons-io:commons-io:2.11.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy:1.14.16=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
net.javacrumbs.json-unit:json-unit-core:2.38.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.minidev:accessors-smart:2.5.1=testRuntimeClasspath
|
||||
net.minidev:json-smart:2.5.1=testRuntimeClasspath
|
||||
com.networknt:json-schema-validator:1.5.7=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
commons-fileupload:commons-fileupload:1.6.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
commons-io:commons-io:2.19.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy:1.15.11=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.java.dev.jna:jna:5.14.0=runtimeClasspath,testRuntimeClasspath
|
||||
net.javacrumbs.json-unit:json-unit-core:2.40.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.minidev:accessors-smart:2.5.0=testRuntimeClasspath
|
||||
net.minidev:json-smart:2.5.0=testRuntimeClasspath
|
||||
net.sf.jopt-simple:jopt-simple:5.0.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apache.httpcomponents.client5:httpclient5:5.3.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apache.httpcomponents.core5:httpcore5-h2:5.2.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apache.httpcomponents.core5:httpcore5:5.2.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
|
||||
org.assertj:assertj-core:3.26.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.checkerframework:checker-qual:3.42.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty.http2:http2-common:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty.http2:http2-hpack:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty.http2:http2-server:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apache.httpcomponents.client5:httpclient5:5.5=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apache.httpcomponents.core5:httpcore5-h2:5.3.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apache.httpcomponents.core5:httpcore5:5.3.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata
|
||||
org.assertj:assertj-core:3.27.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty.http2:http2-common:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty.http2:http2-hpack:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty.http2:http2-server:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty.toolchain:jetty-jakarta-servlet-api:5.0.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-client:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-java-client:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-java-server:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-server:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-bom:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-client:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-http:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-io:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-proxy:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-security:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-server:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-servlet:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-servlets:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-util:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-webapp:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-xml:11.0.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.fusesource.jansi:jansi:2.4.0=default
|
||||
org.fusesource.jansi:jansi:2.4.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.compiler:compiler:23.0.2=compileClasspath,compileOnlyDependenciesMetadata
|
||||
org.graalvm.nativeimage:native-image-base:23.0.2=compileClasspath,compileOnlyDependenciesMetadata
|
||||
org.graalvm.nativeimage:objectfile:23.0.2=compileClasspath,compileOnlyDependenciesMetadata
|
||||
org.graalvm.nativeimage:pointsto:23.0.2=compileClasspath,compileOnlyDependenciesMetadata
|
||||
org.graalvm.nativeimage:svm:23.0.2=compileClasspath,compileOnlyDependenciesMetadata
|
||||
org.graalvm.sdk:graal-sdk:23.0.2=compileClasspath,compileOnlyDependenciesMetadata,default,runtimeClasspath,testRuntimeClasspath
|
||||
org.graalvm.truffle:truffle-api:23.0.2=compileClasspath,compileOnlyDependenciesMetadata,default,runtimeClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-client:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-java-client:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-java-server:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-server:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-bom:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-client:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-http:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-io:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-proxy:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-security:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-server:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-servlet:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-servlets:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-util:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-webapp:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-xml:11.0.24=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.fusesource.jansi:jansi:2.4.2=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.polyglot:polyglot:24.1.2=compileClasspath,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.sdk:collections:24.1.2=compileClasspath,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.sdk:graal-sdk:24.1.2=compileClasspath,compileOnlyDependenciesMetadata,runtimeClasspath,testRuntimeClasspath
|
||||
org.graalvm.sdk:jniutils:24.1.2=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.sdk:nativeimage:24.1.2=compileClasspath,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.sdk:word:24.1.2=compileClasspath,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.truffle:truffle-api:24.1.2=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.truffle:truffle-compiler:24.1.2=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.truffle:truffle-runtime:24.1.2=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.hamcrest:hamcrest:2.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.7.10=kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=apiDependenciesMetadata,compileClasspath,default,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=apiDependenciesMetadata,compileClasspath,default,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10=apiDependenciesMetadata,compileClasspath,default,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.7.10=apiDependenciesMetadata,compileClasspath,default,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains:annotations:13.0=apiDependenciesMetadata,compileClasspath,default,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jline:jline-native:3.23.0=compileClasspath,default,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jline:jline-reader:3.23.0=compileClasspath,default,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jline:jline-terminal-jansi:3.23.0=compileClasspath,default,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jline:jline-terminal:3.23.0=compileClasspath,default,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.jupiter:junit-jupiter-engine:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.jupiter:junit-jupiter-params:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.platform:junit-platform-engine:1.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit:junit-bom:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.msgpack:msgpack-core:0.9.0=default,runtimeClasspath,testRuntimeClasspath
|
||||
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.organicdesign:Paguro:3.10.3=default,runtimeClasspath,testRuntimeClasspath
|
||||
org.slf4j:slf4j-api:2.0.11=testRuntimeClasspath
|
||||
org.slf4j:slf4j-api:2.0.9=testCompileClasspath,testImplementationDependenciesMetadata
|
||||
org.snakeyaml:snakeyaml-engine:2.5=default,runtimeClasspath,testRuntimeClasspath
|
||||
org.wiremock:wiremock:3.6.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.xmlunit:xmlunit-core:2.10.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.xmlunit:xmlunit-legacy:2.10.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.xmlunit:xmlunit-placeholders:2.10.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.yaml:snakeyaml:2.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
empty=annotationProcessor,archives,compile,intransitiveDependenciesMetadata,javaExecutable,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtime,runtimeOnlyDependenciesMetadata,shadow,signatures,sourcesJar,stagedAlpineLinuxAmd64Executable,stagedLinuxAarch64Executable,stagedLinuxAmd64Executable,stagedMacAarch64Executable,stagedMacAmd64Executable,testAnnotationProcessor,testApiDependenciesMetadata,testCompile,testCompileOnly,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDef,testKotlinScriptDefExtensions,testRuntime
|
||||
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-common:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:2.0.21=kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-native-prebuilt:2.0.21=kotlinNativeBundleConfiguration
|
||||
org.jetbrains.kotlin:kotlin-reflect:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.0.21=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.0.21=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.0.21=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains:annotations:13.0=compileClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jetbrains:markdown-jvm:0.7.3=runtimeClasspath,testRuntimeClasspath
|
||||
org.jetbrains:markdown:0.7.3=runtimeClasspath,testRuntimeClasspath
|
||||
org.jline:jline-native:3.23.0=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jline:jline-reader:3.23.0=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jline:jline-terminal-jansi:3.23.0=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jline:jline-terminal:3.23.0=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jspecify:jspecify:1.0.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.13.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-engine:5.13.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-params:5.13.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.13.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-engine:1.13.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-launcher:1.13.3=testRuntimeClasspath
|
||||
org.junit:junit-bom:5.13.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.msgpack:msgpack-core:0.9.8=runtimeClasspath,testRuntimeClasspath
|
||||
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.organicdesign:Paguro:3.10.3=runtimeClasspath,testRuntimeClasspath
|
||||
org.slf4j:slf4j-api:2.0.17=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.snakeyaml:snakeyaml-engine:2.10=runtimeClasspath,testRuntimeClasspath
|
||||
org.wiremock:wiremock:3.13.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.xmlunit:xmlunit-core:2.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.xmlunit:xmlunit-legacy:2.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.xmlunit:xmlunit-placeholders:2.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.yaml:snakeyaml:2.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
empty=annotationProcessor,intransitiveDependenciesMetadata,javaExecutable,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,shadow,signatures,sourcesJar,stagedAlpineLinuxAmd64Executable,stagedLinuxAarch64Executable,stagedLinuxAmd64Executable,stagedMacAarch64Executable,stagedMacAmd64Executable,stagedWindowsAmd64Executable,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions
|
||||
|
||||
@@ -1,19 +1,34 @@
|
||||
import java.security.KeyStore
|
||||
import java.security.cert.CertificateFactory
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.OutputStream
|
||||
import org.gradle.kotlin.dsl.support.serviceOf
|
||||
|
||||
plugins {
|
||||
pklAllProjects
|
||||
pklKotlinLibrary
|
||||
pklPublishLibrary
|
||||
pklNativeBuild
|
||||
pklJavaExecutable
|
||||
pklNativeExecutable
|
||||
`maven-publish`
|
||||
|
||||
// already on build script class path (see buildSrc/build.gradle.kts),
|
||||
// hence must only specify plugin ID here
|
||||
@Suppress("DSL_SCOPE_VIOLATION")
|
||||
id(libs.plugins.shadow.get().pluginId)
|
||||
|
||||
@Suppress("DSL_SCOPE_VIOLATION")
|
||||
alias(libs.plugins.checksum)
|
||||
}
|
||||
|
||||
@@ -31,17 +46,9 @@ publishing {
|
||||
}
|
||||
}
|
||||
|
||||
val stagedMacAmd64Executable: Configuration by configurations.creating
|
||||
val stagedMacAarch64Executable: Configuration by configurations.creating
|
||||
val stagedLinuxAmd64Executable: Configuration by configurations.creating
|
||||
val stagedLinuxAarch64Executable: Configuration by configurations.creating
|
||||
val stagedAlpineLinuxAmd64Executable: Configuration by configurations.creating
|
||||
val stagedWindowsAmd64Executable: Configuration by configurations.creating
|
||||
|
||||
val certs: SourceSet by sourceSets.creating
|
||||
|
||||
dependencies {
|
||||
compileOnly(libs.svm)
|
||||
implementation(libs.truffleRuntime)
|
||||
compileOnly(libs.graalSdk)
|
||||
|
||||
// CliEvaluator exposes PClass
|
||||
api(projects.pklCore)
|
||||
@@ -54,37 +61,18 @@ dependencies {
|
||||
implementation(libs.jlineTerminal)
|
||||
implementation(libs.jlineTerminalJansi)
|
||||
implementation(projects.pklServer)
|
||||
implementation(libs.clikt) {
|
||||
// force clikt to use our version of the kotlin stdlib
|
||||
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib-jdk8")
|
||||
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib-common")
|
||||
}
|
||||
implementation(libs.clikt)
|
||||
|
||||
testImplementation(projects.pklCommonsTest)
|
||||
testImplementation(libs.wiremock)
|
||||
|
||||
fun executableDir(name: String) = files(layout.buildDirectory.dir("executable/$name"))
|
||||
stagedMacAmd64Executable(executableDir("pkl-macos-amd64"))
|
||||
stagedMacAmd64Executable(executableDir("pkl-macos-amd64"))
|
||||
stagedMacAarch64Executable(executableDir("pkl-macos-aarch64"))
|
||||
stagedLinuxAmd64Executable(executableDir("pkl-linux-amd64"))
|
||||
stagedLinuxAarch64Executable(executableDir("pkl-linux-aarch64"))
|
||||
stagedAlpineLinuxAmd64Executable(executableDir("pkl-alpine-linux-amd64"))
|
||||
stagedWindowsAmd64Executable(executableDir("pkl-windows-amd64.exe"))
|
||||
}
|
||||
|
||||
tasks.jar {
|
||||
manifest {
|
||||
attributes += mapOf("Main-Class" to "org.pkl.cli.Main")
|
||||
}
|
||||
|
||||
// not required at runtime
|
||||
exclude("org/pkl/cli/svm/**")
|
||||
manifest.attributes +=
|
||||
mapOf("Main-Class" to "org.pkl.cli.Main", "Add-Exports" to buildInfo.jpmsExportsForJarManifest)
|
||||
}
|
||||
|
||||
tasks.javadoc {
|
||||
enabled = false
|
||||
}
|
||||
tasks.javadoc { enabled = false }
|
||||
|
||||
tasks.shadowJar {
|
||||
archiveFileName.set("jpkl")
|
||||
@@ -92,383 +80,112 @@ tasks.shadowJar {
|
||||
exclude("META-INF/maven/**")
|
||||
exclude("META-INF/upgrade/**")
|
||||
|
||||
// org.antlr.v4.runtime.misc.RuleDependencyProcessor
|
||||
exclude("META-INF/services/javax.annotation.processing.Processor")
|
||||
|
||||
exclude("module-info.*")
|
||||
}
|
||||
|
||||
val javaExecutable by tasks.registering(ExecutableJar::class) {
|
||||
inJar.set(tasks.shadowJar.flatMap { it.archiveFile })
|
||||
outJar.set(layout.buildDirectory.file("executable/jpkl"))
|
||||
val testJavaExecutable by
|
||||
tasks.registering(Test::class) {
|
||||
testClassesDirs = tasks.test.get().testClassesDirs
|
||||
classpath =
|
||||
// compiled test classes
|
||||
sourceSets.test.get().output +
|
||||
// java executable
|
||||
tasks.javaExecutable.get().outputs.files +
|
||||
// test-only dependencies
|
||||
// (test dependencies that are also main dependencies must already be contained in java
|
||||
// executable;
|
||||
// to verify that, we don't want to include them here)
|
||||
(configurations.testRuntimeClasspath.get() - configurations.runtimeClasspath.get())
|
||||
}
|
||||
|
||||
// uncomment for debugging
|
||||
//jvmArgs.addAll("-ea", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005")
|
||||
// Setup `testJavaExecutable` tasks for multi-JDK testing.
|
||||
val testJavaExecutableOnOtherJdks = buildInfo.multiJdkTestingWith(testJavaExecutable)
|
||||
|
||||
// Prepare a run of the fat JAR, optionally with a specific Java launcher.
|
||||
private fun setupJavaExecutableRun(
|
||||
name: String,
|
||||
args: Array<String>,
|
||||
launcher: Provider<JavaLauncher>? = null,
|
||||
configurator: Exec.() -> Unit = {},
|
||||
) =
|
||||
tasks.register(name, Exec::class) {
|
||||
dependsOn(tasks.javaExecutable)
|
||||
val outputFile = layout.buildDirectory.file(name) // dummy output to satisfy up-to-date check
|
||||
outputs.file(outputFile)
|
||||
|
||||
executable =
|
||||
when (launcher) {
|
||||
null -> "java"
|
||||
else -> launcher.get().executablePath.asFile.absolutePath
|
||||
}
|
||||
standardOutput = OutputStream.nullOutputStream()
|
||||
|
||||
args("-jar", tasks.javaExecutable.get().outputs.files.singleFile.toString(), *args)
|
||||
|
||||
doFirst { outputFile.get().asFile.delete() }
|
||||
|
||||
doLast { outputFile.get().asFile.writeText("OK") }
|
||||
|
||||
configurator()
|
||||
}
|
||||
|
||||
val evalTestFlags = arrayOf("eval", "-x", "1 + 1", "pkl:base")
|
||||
|
||||
fun Exec.useRootDirAndSuppressOutput() {
|
||||
workingDir = rootProject.layout.projectDirectory.asFile
|
||||
standardOutput = ByteArrayOutputStream() // we only care that this exec doesn't fail
|
||||
}
|
||||
|
||||
val testJavaExecutable by tasks.registering(Test::class) {
|
||||
testClassesDirs = tasks.test.get().testClassesDirs
|
||||
classpath =
|
||||
// compiled test classes
|
||||
sourceSets.test.get().output +
|
||||
// java executable
|
||||
javaExecutable.get().outputs.files +
|
||||
// test-only dependencies
|
||||
// (test dependencies that are also main dependencies must already be contained in java executable;
|
||||
// to verify that, we don't want to include them here)
|
||||
(configurations.testRuntimeClasspath.get() - configurations.runtimeClasspath.get())
|
||||
}
|
||||
// 0.28 Preparing for JDK21 toolchains revealed that `testStartJavaExecutable` may pass, even though
|
||||
// the evaluator fails. To catch this, we need to test the evaluator. We render the CircleCI config
|
||||
// as a realistic test of the fat JAR.
|
||||
val testEvalJavaExecutable by
|
||||
setupJavaExecutableRun("testEvalJavaExecutable", evalTestFlags) { useRootDirAndSuppressOutput() }
|
||||
|
||||
// Run the same evaluator tests on all configured JDK test versions.
|
||||
val testEvalJavaExecutableOnOtherJdks =
|
||||
buildInfo.jdkTestRange.map { jdkTarget ->
|
||||
setupJavaExecutableRun(
|
||||
"testEvalJavaExecutableJdk${jdkTarget.asInt()}",
|
||||
evalTestFlags,
|
||||
serviceOf<JavaToolchainService>().launcherFor { languageVersion = jdkTarget },
|
||||
) {
|
||||
useRootDirAndSuppressOutput()
|
||||
}
|
||||
}
|
||||
|
||||
tasks.check {
|
||||
dependsOn(testJavaExecutable)
|
||||
}
|
||||
|
||||
// 0.14 Java executable was broken because javaExecutable.jvmArgs wasn't commented out.
|
||||
// To catch this and similar problems, test that Java executable starts successfully.
|
||||
val testStartJavaExecutable by tasks.registering(Exec::class) {
|
||||
dependsOn(javaExecutable)
|
||||
val outputFile =
|
||||
layout.buildDirectory.file("testStartJavaExecutable") // dummy output to satisfy up-to-date check
|
||||
outputs.file(outputFile)
|
||||
|
||||
if (buildInfo.os.isWindows) {
|
||||
executable = "java"
|
||||
args("-jar", javaExecutable.get().outputs.files.singleFile.toString(), "--version")
|
||||
} else {
|
||||
executable = javaExecutable.get().outputs.files.singleFile.toString()
|
||||
args("--version")
|
||||
}
|
||||
|
||||
doFirst { outputFile.get().asFile.delete() }
|
||||
|
||||
doLast { outputFile.get().asFile.writeText("OK") }
|
||||
}
|
||||
|
||||
tasks.check {
|
||||
dependsOn(testStartJavaExecutable)
|
||||
}
|
||||
|
||||
val trustStore = layout.buildDirectory.dir("generateTrustStore/PklCARoots.p12")
|
||||
val trustStorePassword = "password" // no sensitive data to protect
|
||||
|
||||
// generate a trust store for Pkl's built-in CA certificates
|
||||
val generateTrustStore by tasks.registering {
|
||||
inputs.file(certs.resources.singleFile)
|
||||
outputs.file(trustStore)
|
||||
doLast {
|
||||
val certificates = certs.resources.singleFile.inputStream().use { stream ->
|
||||
CertificateFactory.getInstance("X.509").generateCertificates(stream)
|
||||
}
|
||||
KeyStore.getInstance("PKCS12").apply {
|
||||
load(null, trustStorePassword.toCharArray()) // initialize empty trust store
|
||||
for ((index, certificate) in certificates.withIndex()) {
|
||||
setCertificateEntry("cert-$index", certificate)
|
||||
}
|
||||
val trustStoreFile = trustStore.get().asFile
|
||||
trustStoreFile.parentFile.mkdirs()
|
||||
trustStoreFile.outputStream().use { stream ->
|
||||
store(stream, trustStorePassword.toCharArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Exec.configureExecutable(
|
||||
graalVm: BuildInfo.GraalVm,
|
||||
outputFile: Provider<RegularFile>,
|
||||
extraArgs: List<String> = listOf()
|
||||
) {
|
||||
dependsOn(generateTrustStore)
|
||||
|
||||
inputs.files(sourceSets.main.map { it.output })
|
||||
.withPropertyName("mainSourceSets")
|
||||
.withPathSensitivity(PathSensitivity.RELATIVE)
|
||||
inputs.files(configurations.runtimeClasspath)
|
||||
.withPropertyName("runtimeClasspath")
|
||||
.withNormalizer(ClasspathNormalizer::class)
|
||||
val nativeImageCommandName = if (buildInfo.os.isWindows) "native-image.cmd" else "native-image"
|
||||
inputs.files(
|
||||
file(graalVm.baseDir)
|
||||
.resolve("bin/$nativeImageCommandName")
|
||||
)
|
||||
.withPropertyName("graalVmNativeImage")
|
||||
.withPathSensitivity(PathSensitivity.ABSOLUTE)
|
||||
outputs.file(outputFile)
|
||||
outputs.cacheIf { true }
|
||||
|
||||
workingDir(outputFile.map { it.asFile.parentFile })
|
||||
executable = "${graalVm.baseDir}/bin/$nativeImageCommandName"
|
||||
|
||||
// JARs to exclude from the class path for the native-image build.
|
||||
val exclusions = listOf(libs.truffleApi, libs.graalSdk).map { it.get().module.name }
|
||||
// https://www.graalvm.org/22.0/reference-manual/native-image/Options/
|
||||
argumentProviders.add(CommandLineArgumentProvider {
|
||||
buildList {
|
||||
// currently gives a deprecation warning, but we've been told
|
||||
// that the "initialize everything at build time" *CLI* option is likely here to stay
|
||||
add("--initialize-at-build-time=")
|
||||
// needed for messagepack-java (see https://github.com/msgpack/msgpack-java/issues/600)
|
||||
add("--initialize-at-run-time=org.msgpack.core.buffer.DirectBufferAccess")
|
||||
add("--no-fallback")
|
||||
add("-Djavax.net.ssl.trustStore=${trustStore.get().asFile}")
|
||||
add("-Djavax.net.ssl.trustStorePassword=$trustStorePassword")
|
||||
add("-Djavax.net.ssl.trustStoreType=PKCS12")
|
||||
// security property "ocsp.enable=true" is set in Main.kt
|
||||
add("-Dcom.sun.net.ssl.checkRevocation=true")
|
||||
add("-H:IncludeResources=org/pkl/core/stdlib/.*\\.pkl")
|
||||
add("-H:IncludeResources=org/jline/utils/.*")
|
||||
add("-H:IncludeResourceBundles=org.pkl.core.errorMessages")
|
||||
add("--macro:truffle")
|
||||
add("-H:Class=org.pkl.cli.Main")
|
||||
add("-H:Name=${outputFile.get().asFile.name}")
|
||||
// the actual limit (currently) used by native-image is this number + 1400 (idea is to compensate for Truffle's own nodes)
|
||||
add("-H:MaxRuntimeCompileMethods=1800")
|
||||
add("-H:+EnforceMaxRuntimeCompileMethods")
|
||||
add("--enable-url-protocols=http,https")
|
||||
add("-H:+ReportExceptionStackTraces")
|
||||
// disable automatic support for JVM CLI options (puts our main class in full control of argument parsing)
|
||||
add("-H:-ParseRuntimeOptions")
|
||||
// quick build mode: 40% faster compilation, 20% smaller (but presumably also slower) executable
|
||||
if (!buildInfo.isReleaseBuild) {
|
||||
add("-Ob")
|
||||
}
|
||||
// native-image rejects non-existing class path entries -> filter
|
||||
add("--class-path")
|
||||
val pathInput = sourceSets.main.get().output + configurations.runtimeClasspath.get()
|
||||
.filter { it.exists() && !exclusions.any { exclude -> it.name.contains(exclude) } }
|
||||
add(pathInput.asPath)
|
||||
// make sure dev machine stays responsive (15% slowdown on my laptop)
|
||||
val processors = Runtime.getRuntime().availableProcessors() /
|
||||
if (buildInfo.os.isMacOsX && !buildInfo.isCiBuild) 4 else 1
|
||||
add("-J-XX:ActiveProcessorCount=${processors}")
|
||||
addAll(extraArgs)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the pkl CLI for macOS/amd64.
|
||||
*/
|
||||
val macExecutableAmd64: TaskProvider<Exec> by tasks.registering(Exec::class) {
|
||||
dependsOn(":installGraalVmAmd64")
|
||||
configureExecutable(
|
||||
buildInfo.graalVmAmd64,
|
||||
layout.buildDirectory.file("executable/pkl-macos-amd64")
|
||||
dependsOn(
|
||||
testJavaExecutable,
|
||||
testJavaExecutableOnOtherJdks,
|
||||
testEvalJavaExecutable,
|
||||
testEvalJavaExecutableOnOtherJdks,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the pkl CLI for macOS/aarch64.
|
||||
*/
|
||||
val macExecutableAarch64: TaskProvider<Exec> by tasks.registering(Exec::class) {
|
||||
dependsOn(":installGraalVmAarch64")
|
||||
configureExecutable(
|
||||
buildInfo.graalVmAarch64,
|
||||
layout.buildDirectory.file("executable/pkl-macos-aarch64"),
|
||||
listOf(
|
||||
"-H:+AllowDeprecatedBuilderClassesOnImageClasspath"
|
||||
)
|
||||
)
|
||||
tasks.checkNative {
|
||||
dependsOn(":pkl-core:checkNative")
|
||||
dependsOn(":pkl-server:checkNative")
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the pkl CLI for linux/amd64.
|
||||
*/
|
||||
val linuxExecutableAmd64: TaskProvider<Exec> by tasks.registering(Exec::class) {
|
||||
dependsOn(":installGraalVmAmd64")
|
||||
configureExecutable(
|
||||
buildInfo.graalVmAmd64,
|
||||
layout.buildDirectory.file("executable/pkl-linux-amd64")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the pkl CLI for linux/aarch64.
|
||||
*
|
||||
* Right now, this is built within a container on Mac using emulation because CI does not have
|
||||
* ARM instances.
|
||||
*/
|
||||
val linuxExecutableAarch64: TaskProvider<Exec> by tasks.registering(Exec::class) {
|
||||
dependsOn(":installGraalVmAarch64")
|
||||
configureExecutable(
|
||||
buildInfo.graalVmAarch64,
|
||||
layout.buildDirectory.file("executable/pkl-linux-aarch64")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a statically linked CLI for linux/amd64.
|
||||
*
|
||||
* Note: we don't publish the same for linux/aarch64 because native-image doesn't support this.
|
||||
* Details: https://www.graalvm.org/22.0/reference-manual/native-image/ARM64/
|
||||
*/
|
||||
val alpineExecutableAmd64: TaskProvider<Exec> by tasks.registering(Exec::class) {
|
||||
dependsOn(":installGraalVmAmd64")
|
||||
configureExecutable(
|
||||
buildInfo.graalVmAmd64,
|
||||
layout.buildDirectory.file("executable/pkl-alpine-linux-amd64"),
|
||||
listOf("--static", "--libc=musl")
|
||||
)
|
||||
}
|
||||
|
||||
val windowsExecutableAmd64: TaskProvider<Exec> by tasks.registering(Exec::class) {
|
||||
dependsOn(":installGraalVmAmd64")
|
||||
configureExecutable(
|
||||
buildInfo.graalVmAmd64,
|
||||
layout.buildDirectory.file("executable/pkl-windows-amd64"),
|
||||
listOf("-Dfile.encoding=UTF-8", "-march=compatibility")
|
||||
)
|
||||
}
|
||||
|
||||
tasks.assembleNative {
|
||||
when {
|
||||
buildInfo.os.isMacOsX -> {
|
||||
dependsOn(macExecutableAmd64)
|
||||
if (buildInfo.arch == "aarch64") {
|
||||
dependsOn(macExecutableAarch64)
|
||||
}
|
||||
}
|
||||
|
||||
buildInfo.os.isWindows -> {
|
||||
dependsOn(windowsExecutableAmd64)
|
||||
}
|
||||
|
||||
buildInfo.os.isLinux && buildInfo.arch == "aarch64" -> {
|
||||
dependsOn(linuxExecutableAarch64)
|
||||
}
|
||||
|
||||
buildInfo.os.isLinux && buildInfo.arch == "amd64" -> {
|
||||
dependsOn(linuxExecutableAmd64)
|
||||
if (buildInfo.hasMuslToolchain) {
|
||||
dependsOn(alpineExecutableAmd64)
|
||||
}
|
||||
}
|
||||
}
|
||||
executable {
|
||||
name = "pkl"
|
||||
javaName = "jpkl"
|
||||
documentationName = "Pkl CLI"
|
||||
publicationName = "pkl-cli"
|
||||
javaPublicationName = "pkl-cli-java"
|
||||
mainClass = "org.pkl.cli.Main"
|
||||
website = "https://pkl-lang.org/main/current/pkl-cli/index.html"
|
||||
}
|
||||
|
||||
// make Java executable available to other subprojects
|
||||
// (we don't do the same for native executables because we don't want tasks assemble/build to build them)
|
||||
// (we don't do the same for native executables because we don't want tasks assemble/build to build
|
||||
// them)
|
||||
artifacts {
|
||||
add("javaExecutable", javaExecutable.map { it.outputs.files.singleFile }) {
|
||||
add("javaExecutable", tasks.javaExecutable.map { it.outputs.files.singleFile }) {
|
||||
name = "pkl-cli-java"
|
||||
classifier = null
|
||||
extension = "jar"
|
||||
builtBy(javaExecutable)
|
||||
builtBy(tasks.javaExecutable)
|
||||
}
|
||||
}
|
||||
|
||||
//region Maven Publishing
|
||||
publishing {
|
||||
publications {
|
||||
register<MavenPublication>("javaExecutable") {
|
||||
artifactId = "pkl-cli-java"
|
||||
|
||||
artifact(javaExecutable.map { it.outputs.files.singleFile }) {
|
||||
classifier = null
|
||||
extension = "jar"
|
||||
builtBy(javaExecutable)
|
||||
}
|
||||
|
||||
pom {
|
||||
url.set("https://github.com/apple/pkl/tree/main/pkl-cli")
|
||||
description.set(
|
||||
"""
|
||||
Pkl CLI executable for Java.
|
||||
Can be executed directly on *nix (if the `java` command is found on the PATH) and with `java -jar` otherwise.
|
||||
Requires Java 17 or higher.
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
create<MavenPublication>("macExecutableAmd64") {
|
||||
artifactId = "pkl-cli-macos-amd64"
|
||||
artifact(stagedMacAmd64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedMacAmd64Executable)
|
||||
}
|
||||
pom {
|
||||
name.set("pkl-cli-macos-amd64")
|
||||
url.set("https://github.com/apple/pkl/tree/main/pkl-cli")
|
||||
description.set("Native Pkl CLI executable for macOS/amd64.")
|
||||
}
|
||||
}
|
||||
create<MavenPublication>("macExecutableAarch64") {
|
||||
artifactId = "pkl-cli-macos-aarch64"
|
||||
artifact(stagedMacAarch64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedMacAarch64Executable)
|
||||
}
|
||||
pom {
|
||||
name.set("pkl-cli-macos-aarch64")
|
||||
url.set("https://github.com/apple/pkl/tree/main/pkl-cli")
|
||||
description.set("Native Pkl CLI executable for macOS/aarch64.")
|
||||
}
|
||||
}
|
||||
create<MavenPublication>("linuxExecutableAmd64") {
|
||||
artifactId = "pkl-cli-linux-amd64"
|
||||
artifact(stagedLinuxAmd64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedLinuxAmd64Executable)
|
||||
}
|
||||
pom {
|
||||
name.set("pkl-cli-linux-amd64")
|
||||
url.set("https://github.com/apple/pkl/tree/main/pkl-cli")
|
||||
description.set("Native Pkl CLI executable for linux/amd64.")
|
||||
}
|
||||
}
|
||||
create<MavenPublication>("linuxExecutableAarch64") {
|
||||
artifactId = "pkl-cli-linux-aarch64"
|
||||
artifact(stagedLinuxAarch64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedLinuxAarch64Executable)
|
||||
}
|
||||
pom {
|
||||
name.set("pkl-cli-linux-aarch64")
|
||||
url.set("https://github.com/apple/pkl/tree/main/pkl-cli")
|
||||
description.set("Native Pkl CLI executable for linux/aarch64.")
|
||||
}
|
||||
}
|
||||
create<MavenPublication>("alpineLinuxExecutableAmd64") {
|
||||
artifactId = "pkl-cli-alpine-linux-amd64"
|
||||
artifact(stagedAlpineLinuxAmd64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "bin"
|
||||
builtBy(stagedAlpineLinuxAmd64Executable)
|
||||
}
|
||||
pom {
|
||||
name.set("pkl-cli-alpine-linux-amd64")
|
||||
url.set("https://github.com/apple/pkl/tree/main/pkl-cli")
|
||||
description.set("Native Pkl CLI executable for linux/amd64 and statically linked to musl.")
|
||||
}
|
||||
}
|
||||
|
||||
create<MavenPublication>("windowsExecutableAmd64") {
|
||||
artifactId = "pkl-cli-windows-amd64"
|
||||
artifact(stagedWindowsAmd64Executable.singleFile) {
|
||||
classifier = null
|
||||
extension = "exe"
|
||||
builtBy(stagedWindowsAmd64Executable)
|
||||
}
|
||||
pom {
|
||||
name.set("pkl-cli-windows-amd64")
|
||||
url.set("https://github.com/apple/pkl/tree/main/pkl-cli")
|
||||
description.set("Native Pkl CLI executable for windows/amd64.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signing {
|
||||
sign(publishing.publications["javaExecutable"])
|
||||
sign(publishing.publications["linuxExecutableAarch64"])
|
||||
sign(publishing.publications["linuxExecutableAmd64"])
|
||||
sign(publishing.publications["macExecutableAarch64"])
|
||||
sign(publishing.publications["macExecutableAmd64"])
|
||||
sign(publishing.publications["alpineLinuxExecutableAmd64"])
|
||||
sign(publishing.publications["windowsExecutableAmd64"])
|
||||
}
|
||||
//endregion
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,22 +16,26 @@
|
||||
package org.pkl.cli
|
||||
|
||||
import java.io.File
|
||||
import java.io.Reader
|
||||
import java.io.Writer
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.net.URI
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.StandardOpenOption
|
||||
import kotlin.io.path.createParentDirectories
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.io.path.writeBytes
|
||||
import org.pkl.commons.cli.CliCommand
|
||||
import org.pkl.commons.cli.CliException
|
||||
import org.pkl.commons.createParentDirectories
|
||||
import org.pkl.commons.currentWorkingDir
|
||||
import org.pkl.commons.writeString
|
||||
import org.pkl.core.Closeables
|
||||
import org.pkl.core.Evaluator
|
||||
import org.pkl.core.EvaluatorBuilder
|
||||
import org.pkl.core.ModuleSource
|
||||
import org.pkl.core.PklException
|
||||
import org.pkl.core.module.ModuleKeyFactories
|
||||
import org.pkl.core.module.ModulePathResolver
|
||||
import org.pkl.core.runtime.ModuleResolver
|
||||
import org.pkl.core.runtime.VmException
|
||||
@@ -47,13 +51,14 @@ constructor(
|
||||
private val options: CliEvaluatorOptions,
|
||||
// use System.{in,out}() rather than System.console()
|
||||
// because the latter returns null when output is sent through a unix pipe
|
||||
private val consoleReader: Reader = System.`in`.reader(),
|
||||
private val consoleWriter: Writer = System.out.writer(),
|
||||
private val inputStream: InputStream = System.`in`,
|
||||
private val outputStream: OutputStream = System.out,
|
||||
) : CliCommand(options.base) {
|
||||
/**
|
||||
* Output files for the modules to be evaluated. Returns `null` if `options.outputPath` is `null`.
|
||||
* Multiple modules may be mapped to the same output file, in which case their outputs are
|
||||
* concatenated with [CliEvaluatorOptions.moduleOutputSeparator].
|
||||
* Output files for the modules to be evaluated. Returns `null` if `options.outputPath` is `null`
|
||||
* or if `options.multipleFileOutputPath` is not `null`. Multiple modules may be mapped to the
|
||||
* same output file, in which case their outputs are concatenated with
|
||||
* [CliEvaluatorOptions.moduleOutputSeparator].
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
val outputFiles: Set<File>? by lazy {
|
||||
@@ -82,11 +87,12 @@ constructor(
|
||||
/**
|
||||
* Evaluates source modules according to [options].
|
||||
*
|
||||
* If [CliEvaluatorOptions.outputPath] is set, each module's `output.text` is written to the
|
||||
* module's [output file][outputFiles]. If [CliEvaluatorOptions.multipleFileOutputPath] is set,
|
||||
* each module's `output.files` are written to the module's [output directory][outputDirectories].
|
||||
* Otherwise, each module's `output.text` is written to [consoleWriter] (which defaults to
|
||||
* standard out).
|
||||
* If [CliEvaluatorOptions.outputPath] is set, each module's `output.bytes` is written to the
|
||||
* module's [output file][outputFiles].
|
||||
*
|
||||
* If [CliEvaluatorOptions.multipleFileOutputPath] is set, each module's `output.files` are
|
||||
* written to the module's [output directory][outputDirectories]. Otherwise, each module's
|
||||
* `output.bytes` is written to [outputStream] (which defaults to standard out).
|
||||
*
|
||||
* Throws [CliException] in case of an error.
|
||||
*/
|
||||
@@ -99,7 +105,8 @@ constructor(
|
||||
writeOutput(builder)
|
||||
}
|
||||
} finally {
|
||||
ModuleKeyFactories.closeQuietly(builder.moduleKeyFactories)
|
||||
Closeables.closeQuietly(builder.moduleKeyFactories)
|
||||
Closeables.closeQuietly(builder.resourceReaders)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +125,7 @@ constructor(
|
||||
try {
|
||||
moduleResolver.resolve(uri)
|
||||
} catch (e: VmException) {
|
||||
throw e.toPklException(stackFrameTransformer)
|
||||
throw e.toPklException(stackFrameTransformer, options.base.color?.hasColor() ?: false)
|
||||
}
|
||||
val substituted =
|
||||
pathStr
|
||||
@@ -136,10 +143,29 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
/** Renders each module's `output.text`, writing it to the specified output file. */
|
||||
private fun Evaluator.writeOutput(moduleSource: ModuleSource, writeTo: Path): Boolean {
|
||||
if (options.expression == null) {
|
||||
val bytes = evaluateOutputBytes(moduleSource)
|
||||
writeTo.writeBytes(bytes)
|
||||
return bytes.isNotEmpty()
|
||||
}
|
||||
val text = evaluateExpressionString(moduleSource, options.expression)
|
||||
writeTo.writeString(text)
|
||||
return text.isNotEmpty()
|
||||
}
|
||||
|
||||
private fun Evaluator.evalOutput(moduleSource: ModuleSource): ByteArray {
|
||||
if (options.expression == null) {
|
||||
return evaluateOutputBytes(moduleSource)
|
||||
}
|
||||
return evaluateExpressionString(moduleSource, options.expression)
|
||||
.toByteArray(StandardCharsets.UTF_8)
|
||||
}
|
||||
|
||||
/** Renders each module's `output.bytes`, writing it to the specified output file. */
|
||||
private fun writeOutput(builder: EvaluatorBuilder) {
|
||||
val evaluator = builder.setOutputFormat(options.outputFormat).build()
|
||||
evaluator.use {
|
||||
evaluator.use { ev ->
|
||||
val outputFiles = fileOutputPaths
|
||||
if (outputFiles != null) {
|
||||
// files that we've written non-empty output to
|
||||
@@ -148,12 +174,18 @@ constructor(
|
||||
val writtenFiles = mutableSetOf<Path>()
|
||||
|
||||
for ((moduleUri, outputFile) in outputFiles) {
|
||||
val moduleSource = toModuleSource(moduleUri, consoleReader)
|
||||
val output = evaluator.evaluateExpressionString(moduleSource, options.expression)
|
||||
val moduleSource = toModuleSource(moduleUri, inputStream)
|
||||
if (Files.isDirectory(outputFile)) {
|
||||
throw CliException(
|
||||
"Output file `$outputFile` is a directory. " +
|
||||
"Did you mean `--multiple-file-output-path`?"
|
||||
)
|
||||
}
|
||||
val output = ev.evalOutput(moduleSource)
|
||||
outputFile.createParentDirectories()
|
||||
if (!writtenFiles.contains(outputFile)) {
|
||||
// write file even if output is empty to overwrite output from previous runs
|
||||
outputFile.writeString(output)
|
||||
outputFile.writeBytes(output)
|
||||
if (output.isNotEmpty()) {
|
||||
writtenFiles.add(outputFile)
|
||||
}
|
||||
@@ -163,36 +195,51 @@ constructor(
|
||||
options.moduleOutputSeparator + '\n',
|
||||
Charsets.UTF_8,
|
||||
StandardOpenOption.WRITE,
|
||||
StandardOpenOption.APPEND
|
||||
)
|
||||
outputFile.writeString(
|
||||
output,
|
||||
Charsets.UTF_8,
|
||||
StandardOpenOption.WRITE,
|
||||
StandardOpenOption.APPEND
|
||||
StandardOpenOption.APPEND,
|
||||
)
|
||||
outputFile.writeBytes(output, StandardOpenOption.WRITE, StandardOpenOption.APPEND)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var outputWritten = false
|
||||
for (moduleUri in options.base.normalizedSourceModules) {
|
||||
val moduleSource = toModuleSource(moduleUri, consoleReader)
|
||||
val output = evaluator.evaluateExpressionString(moduleSource, options.expression)
|
||||
if (output.isNotEmpty()) {
|
||||
if (outputWritten) consoleWriter.appendLine(options.moduleOutputSeparator)
|
||||
consoleWriter.write(output)
|
||||
consoleWriter.flush()
|
||||
outputWritten = true
|
||||
val moduleSource = toModuleSource(moduleUri, inputStream)
|
||||
if (options.expression != null) {
|
||||
val output = evaluator.evaluateExpressionString(moduleSource, options.expression)
|
||||
if (output.isNotEmpty()) {
|
||||
if (outputWritten) outputStream.writeLine(options.moduleOutputSeparator)
|
||||
outputStream.writeText(output)
|
||||
outputStream.flush()
|
||||
outputWritten = true
|
||||
}
|
||||
} else {
|
||||
val outputBytes = evaluator.evaluateOutputBytes(moduleSource)
|
||||
if (outputBytes.isNotEmpty()) {
|
||||
if (outputWritten) outputStream.writeLine(options.moduleOutputSeparator)
|
||||
outputStream.write(outputBytes)
|
||||
outputStream.flush()
|
||||
outputWritten = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun toModuleSource(uri: URI, reader: Reader) =
|
||||
if (uri == VmUtils.REPL_TEXT_URI) ModuleSource.create(uri, reader.readText())
|
||||
else ModuleSource.uri(uri)
|
||||
private fun OutputStream.writeText(text: String) = write(text.toByteArray())
|
||||
|
||||
private fun OutputStream.writeLine(text: String) {
|
||||
writeText(text)
|
||||
writeText("\n")
|
||||
}
|
||||
|
||||
private fun toModuleSource(uri: URI, reader: InputStream) =
|
||||
if (uri == VmUtils.REPL_TEXT_URI) {
|
||||
ModuleSource.create(uri, reader.readAllBytes().toString(StandardCharsets.UTF_8))
|
||||
} else {
|
||||
ModuleSource.uri(uri)
|
||||
}
|
||||
|
||||
private fun checkPathSpec(pathSpec: String) {
|
||||
val illegal = pathSpec.indexOfFirst { IoUtils.isReservedFilenameChar(it) && it != '/' }
|
||||
@@ -214,7 +261,7 @@ constructor(
|
||||
if (outputDir.exists() && !outputDir.isDirectory()) {
|
||||
throw CliException("Output path `$outputDir` exists and is not a directory.")
|
||||
}
|
||||
val moduleSource = toModuleSource(moduleUri, consoleReader)
|
||||
val moduleSource = toModuleSource(moduleUri, inputStream)
|
||||
val output = evaluator.evaluateOutputFiles(moduleSource)
|
||||
for ((pathSpec, fileOutput) in output) {
|
||||
checkPathSpec(pathSpec)
|
||||
@@ -238,12 +285,12 @@ constructor(
|
||||
}
|
||||
writtenFiles[realPath] = OutputFile(pathSpec, moduleUri)
|
||||
realPath.createParentDirectories()
|
||||
realPath.writeString(fileOutput.text)
|
||||
consoleWriter.write(
|
||||
realPath.writeBytes(fileOutput.bytes)
|
||||
outputStream.writeText(
|
||||
IoUtils.relativize(resolvedPath, currentWorkingDir).toString() +
|
||||
IoUtils.getLineSeparator()
|
||||
)
|
||||
consoleWriter.flush()
|
||||
outputStream.flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -74,12 +74,12 @@ data class CliEvaluatorOptions(
|
||||
*
|
||||
* If set, the said expression is evaluated under the context of the enclosing module.
|
||||
*
|
||||
* If unset, the module's `output.text` property evaluated.
|
||||
* If unset, the module's `output.bytes` property is evaluated.
|
||||
*/
|
||||
val expression: String = "output.text",
|
||||
val expression: String? = null,
|
||||
) {
|
||||
|
||||
companion object {
|
||||
val defaults = CliEvaluatorOptions(CliBaseOptions())
|
||||
val defaults: CliEvaluatorOptions = CliEvaluatorOptions(CliBaseOptions())
|
||||
}
|
||||
}
|
||||
|
||||
80
pkl-cli/src/main/kotlin/org/pkl/cli/CliImportAnalyzer.kt
Normal file
80
pkl-cli/src/main/kotlin/org/pkl/cli/CliImportAnalyzer.kt
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.cli
|
||||
|
||||
import java.io.Writer
|
||||
import kotlin.io.path.createParentDirectories
|
||||
import org.pkl.commons.cli.CliCommand
|
||||
import org.pkl.commons.writeString
|
||||
import org.pkl.core.Closeables
|
||||
import org.pkl.core.ModuleSource
|
||||
|
||||
class CliImportAnalyzer
|
||||
@JvmOverloads
|
||||
constructor(
|
||||
private val options: CliImportAnalyzerOptions,
|
||||
private val consoleWriter: Writer = System.out.writer(),
|
||||
) : CliCommand(options.base) {
|
||||
|
||||
override fun doRun() {
|
||||
val rendered = render()
|
||||
if (options.outputPath != null) {
|
||||
options.outputPath.createParentDirectories()
|
||||
options.outputPath.writeString(rendered)
|
||||
} else {
|
||||
consoleWriter.write(rendered)
|
||||
consoleWriter.flush()
|
||||
}
|
||||
}
|
||||
|
||||
// language=pkl
|
||||
private val sourceModule =
|
||||
ModuleSource.text(
|
||||
"""
|
||||
import "pkl:analyze"
|
||||
|
||||
local importStrings = read*("prop:pkl.analyzeImports.**").toMap().values.toSet()
|
||||
|
||||
output {
|
||||
value = analyze.importGraph(importStrings)
|
||||
renderer {
|
||||
converters {
|
||||
[Map] = (it) -> it.toMapping()
|
||||
[Set] = (it) -> it.toListing()
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
private fun render(): String {
|
||||
val builder = evaluatorBuilder().setOutputFormat(options.outputFormat)
|
||||
try {
|
||||
return builder
|
||||
.apply {
|
||||
for ((idx, sourceModule) in options.base.normalizedSourceModules.withIndex()) {
|
||||
addExternalProperty("pkl.analyzeImports.$idx", sourceModule.toString())
|
||||
}
|
||||
}
|
||||
.build()
|
||||
.use { it.evaluateOutputText(sourceModule) }
|
||||
} finally {
|
||||
Closeables.closeQuietly(builder.moduleKeyFactories)
|
||||
Closeables.closeQuietly(builder.resourceReaders)
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user