71 Commits

Author SHA1 Message Date
Jen Basch
6a3722a471 Prepare 0.29.1 release 2025-08-27 13:46:31 -07:00
Daniel Chao
2a7195125c Prepare 0.29.1 release (#1191) 2025-08-27 13:32:08 -07:00
Artem Yarmoliuk
f0896ba16f Fix shell completion for paths (#1161) 2025-08-26 10:50:08 -07:00
Daniel Chao
9f7997bbc4 Fix missing resources in native pkldoc, and disable test mode (#1175)
This fixes two issues:

1. Test mode is enabled in pkldoc without the ability to turn it off
2. Native pkldoc is missing required resources

This also adds tests for both `jpkldoc` and `pkldoc`.
2025-08-26 10:49:56 -07:00
Daniel Chao
245b53bc8a Add docs for installing via winget (#1171) 2025-08-26 10:49:45 -07:00
Daniel Chao
9a92d75fcb Fix escaping in yaml strings (#1165)
The backslash needs to be escaped when rendering double-quoted YAML strings.

In addition, this escapes the following characters:

* next line (0x85)
* nbsp (0xa0)
2025-08-26 10:49:39 -07:00
Daniel Chao
419127fb0d Fix encoding for mapping with local members (#1152)
Fixes an issue where local members are included in
the mapping entry count.

Also: avoid re-computing Mapping.length
2025-08-26 10:49:20 -07:00
Jen Basch
f7951510b9 Correctly handle EOF after unmatched backtick (#1187) 2025-08-25 14:35:12 -07:00
Daniel Chao
1b49ec9422 Fix download links (#1162)
* Snapshot repo has changed
* Fix a bug where pkl-codegen-java download link points to Sonatype instead of GitHub

Not in the PR: we also need to fix the snapshot download location;
but haven't figured out yet what the correct link is.
2025-07-31 08:44:22 -07:00
Dan Chao
bdabcea216 Add link to 0.29 release notes 2025-07-24 10:55:05 -07:00
Islon Scherer
5f00f9c82e Prepare 0.29.0 release 2025-07-24 19:07:40 +02:00
Daniel Chao
efee9f3801 Disable publishing jpkl (#1147)
This is causing a breakage in our release pipeline right now.
2025-07-24 10:04:46 -07:00
Daniel Chao
8e88133248 Disable publishing native executables to Maven Central (#1146)
Attempts to publish these artifacts is resulting in errors like
"No Archiver found for the stream signature"

Also, add to release notes
2025-07-24 09:21:02 -07:00
Daniel Chao
b38b15ba71 Remove duplicate block ids (#1145)
We can't repeat these block ids multiple times in the same page.
2025-07-24 17:19:29 +02:00
Daniel Chao
1c4fbe7c1c Fix: use http.rewrites to configure the evaluator in message passing API (#1141)
This is a bugfix, where the `rewrites` option is currently ignored.

Also: return any illegal argument errors from creating the evaluator as
an error in the CreateEvaluatorResponse
2025-07-24 07:30:31 -07:00
Daniel Chao
ae046a804b Add release notes for 0.29 (#1140)
Co-authored-by: Jen Basch <421772+HT154@users.noreply.github.com>
2025-07-24 07:30:04 -07:00
Daniel Chao
53f6951d81 Add bytesType to pkl:reflect (#1144)
Just like other data types on the base module, the mirror for `Bytes`
should be available directly on `pkl:reflect`.
2025-07-24 06:21:10 -07:00
Daniel Chao
7c8c4438d5 Defer noProxy to settings.pkl or PklProject if not set explicitly (#1143)
Fixes an issue where `http.noProxy` settings are ignored.
2025-07-23 10:57:31 -07:00
Daniel Chao
bdf6aa6b60 Un-deprecate Resource.base64, compute bytes/base64 in terms of each other (#1138)
This makes changes to avoid a needless breaking change.
It preserves code like `new Resource { base64 = someValue }.sha256`,
and also code that renders `Resource` into static formats.

Co-authored-by: Islon Scherer <islonscherer@gmail.com>
2025-07-23 06:25:49 -07:00
Daniel Chao
03d8e01801 Bump GraalVM JDK version to 21.0.8 (#1139) 2025-07-23 05:22:17 -07:00
Jen Basch
85e4f133a4 Add getOrDefault method to Listing and Mapping (#1053)
This PR adds methods to Listing and Mapping that can be used to retrieve members. If the member for the index/key isn't present, it applies default to the index/key. In both cases, this is essentially sugar for getOrNull(<index/key>) ?? default.apply(<index/key>).

Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>
2025-07-22 15:45:49 -07:00
Daniel Chao
306a3b0fc2 Polish http rewrites (#1133)
* Polish rewrite docs
* Add documentation comments, add missing evaluator options
* Add ability to set HTTP builder in ConfigEvaluatorBuilder
* Add ability to set rewrites in executor API
2025-07-22 15:42:07 -07:00
Daniel Chao
fe064960b4 Bump Gradle to 8.14.3 (#1129) 2025-07-18 11:03:38 -07:00
Daniel Chao
6cd73227a1 Update dependencies (#1128) 2025-07-18 09:29:44 -07:00
Islon Scherer
ba82c5c6d6 Only allow shebangs in the beginning of a module (#1126) 2025-07-18 11:18:45 +02:00
Daniel Chao
decb4ea66e Improve message passing api docs (#1127)
1. Change `Binary` to `Bytes` (new type representing binary data)
2. Add documentation for `http.rewrites` option
2025-07-17 07:57:48 -07:00
Daniel Chao
99020bb79d Add support for HTTP rewrites (#1062)
This adds a new configuration option for the HTTP client to replace URI prefixes when making outbound calls.

Follows the design of https://github.com/apple/pkl-evolution/pull/17
2025-07-16 15:53:31 -07:00
Daniel Chao
fea031a138 Switch publishing to sonatype central (#1121)
OSSRH is now EOL, so we need to publish to this new repository.
2025-07-11 05:48:31 -07:00
Daniel Chao
48ad4386c8 Add Kotlin support for "addGeneratedAnnotation" flag (#1115)
This adds logic so that the Kotlin code generator also supports the
"addGeneratedAnnotation" flag.

Also:
* Add Antora documentation
* Adjust names (generated-annotation -> add-generated-annotation)
* Adjust doc comments
2025-07-08 14:05:15 -07:00
Islon Scherer
3a35be6311 Remove ANTLR from the repo (#1114) 2025-07-08 09:43:35 +02:00
André Rouél
0973774a5d Add @Generated annotation to generated Java types (#1075)
JaCoCo automatically excludes methods and classes annotated with @Generated from the coverage reports. This is very important to us as generated code should not normally be included in the coverage report. We want to measure the coverage of the code that we actually wrote and maintain, not the code that was automatically generated by tools.

By introducing a property generatedAnnotation (default value false) one could enable writing @Generated on Java types to be generated.

Co-authored-by: Nullpointer <mike.schulze@tealium.com>
2025-07-07 15:31:49 -07:00
Jen Basch
dbf57280ba Fix crash due to parse error in module header (#1112) 2025-07-01 10:05:16 +02:00
Artem Yarmoliuk
f1388ffb2f Don't show 100% when number of failures is rounded up (#1110)
Co-Authored-By: Mike Drob <mdrob@apple.com>
2025-06-27 15:29:26 +02:00
Daniel Chao
d6fd7e0942 Fix native build (#1099)
* Add truffle boundaries
* Fix snippet output tests
* Make java LanguageSnippetTests eval output.bytes, just like the CLI does
2025-06-17 08:42:49 -07:00
Daniel Chao
e9320557b7 Introduces Bytes class (#1019)
This introduces a new `Bytes` standard library class, for working with
binary data.

* Add Bytes class to the standard library
* Change CLI to eval `output.bytes`
* Change code generators to map Bytes to respective underlying type
* Add subscript and concat operator support
* Add binary encoding for Bytes
* Add PCF and Plist rendering for Bytes

Co-authored-by: Kushal Pisavadia <kushi.p@gmail.com>
2025-06-11 16:23:55 -07:00
Artem Yarmoliuk
3bd8a88506 Aggregate junit report into one file (#1056)
Some systems require junit report to be in a single file. For example `bazel` https://bazel.build/reference/test-encyclopedia needs single file to be available in `XML_OUTPUT_FILE` path.

To avoid implementing junit aggregation in pkl wrappers in different places this PR instead adds a `--junit-aggregate-reports` flag to return all junit reports as a single file.

Additional flag `--junit-aggregate-suite-name` is added to allow overriding global test suite name from default `pkl-tests`
2025-06-06 17:33:13 -07:00
Daniel Chao
0b0f3b131d Add ResourceReaders#fromServiceProviders to preconfigured evaluator (#1094)
The preconfigured evaluator currently adds 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`).
2025-06-06 17:26:38 -07:00
Daniel Chao
568c6ccbc2 Update dependencies, and clean up multi-JDK testing (#1088)
* Update dependencies
  1. Remove */gradle.lockfile files
  2. Run `gradle updateDependencyLocks` and commit
* Update multi-JDK testing to use simple Test task, add junit-platform-launcher to dependencies
  - Don't use JvmTestSuite (we don't use another test runner, we use the same classpath)
* Add junit-platform-launcher to libs (prevent an issue where junit-engine and junit-launcher can fall out of sync)
2025-06-04 08:30:02 -07:00
Daniel Chao
dd9800c70a Update Gradle to 8.14.1 (#1091) 2025-06-04 08:28:52 -07:00
Daniel Chao
2bc9c2f424 Treat opaque file URIs as errors (#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 analyze what it resolves as.

According to RFC-8089, File URIs must have paths that start with `/`. So, these are actually _not valid URIs_.
See the grammar defined in https://datatracker.ietf.org/doc/html/rfc8089#section-2

This changes Pkl's behavior so that these URIs are treated as errors.
2025-06-03 14:57:22 -07:00
Daniel Chao
4eeb61dc74 Fix multi-jdk testing setup (#1086)
This changes the Gradle build to always create multi-jdk tasks,
and instead use the `enabled` property to determine whether the task
is actually ran or not.

The has the following benefits:
* IntelliJ and other tools understand the task execution graph (e.g. testJdk20 shows up as a task)
* JDK-specific Gradle configurations always exist, so `updateDependencyLocks` is consistent.
2025-06-03 08:56:02 -07:00
Vladimir Sitnikov
7d50c46c29 Use javac -release and kotlinc -Xjdk-release (#1080)
The change ensures the generated bytecode adheres to the APIs
for the target Java release.

Previously, only sourceCompatibility and targetCompatibility were used,
and they might cause issues like NoSuchMethodError when a newer javac
compiles with -target older_release.

Note: it is good to use a new an up to date javac to avoid issues
in the compiler itself, so having a proper `-release ..` configuration
is vital.

See https://www.morling.dev/blog/bytebuffer-and-the-dreaded-nosuchmethoderr
2025-05-28 09:38:53 -07:00
Islon Scherer
a19e6bf684 Fix doc dependency link (#1078) 2025-05-28 18:08:38 +02:00
Jen Basch
021f43bec4 I'm Jen! (#1072) 2025-05-19 11:55:24 -07:00
Islon Scherer
fe2e4aa1a4 Simplify precedence and associativity parsing (#1066) 2025-05-12 14:59:26 +02:00
Josh B
948a20ad0c Add mapNonNullIndexed API to List and Set (#1063) 2025-05-08 15:57:28 +02:00
Sitaktif
919d63e51a docs: fixed referenced property in "fixed" section (#1065) 2025-05-08 15:52:40 +02:00
Artem Yarmoliuk
e4716c9e45 Add command to generate shell completion (#1052)
Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>
Co-authored-by: Islon Scherer <islonscherer@gmail.com>
2025-05-01 08:39:30 -07:00
Daniel Chao
49a593f5c9 Add release notes for 0.28.2 (#1043) 2025-04-17 08:58:56 -07:00
Daniel Chao
e98b42cffd Fix incorrect substring (#1028)
The relative path should be based off the module name prefix, not the
package name.
2025-04-14 16:22:46 -07:00
Daniel Chao
38c44860d4 Fix compiler error in benchmark (#1040) 2025-04-11 16:08:20 -07:00
Jeroen Soeters
854074e619 Do not crash, but suggest '--multiple-file-output-path' when specifying a directory as output file (#1038)
When specifying a directory instead of a file for the output, pkl won't crash anymore, but instead output an error message, suggesting --multiple-file-output-path.
2025-04-08 10:56:15 -07:00
mbvissers
3119e0781b Fix typo in evolution-and-roadmap.adoc (#1031) 2025-04-01 11:34:47 -07:00
Daniel Chao
b445713b8c Publish executables for pkldoc, pkl-codegen-java, pkl-codegen-kotlin (#1023)
This adds logic to build and publish the other executables related to Pkl.

These are:

* pkl-doc
* pkl-codegen-kotlin
* pkl-codegen-java

pkl-codegen-kotlin and pkl-codegen-java are published as executable JARs, whereas pkldoc is published both as an executable JAR, and also native executables (matching the set of os/arch supported by Pkl).

The reason this only publishes executable JARs for pkl-codegen-kotlin and pkl-codegen-java is because we expect that the Java requirement is not a problem for these users, and that the native executable provides negligible added value.

As part of this, the following changes are made:

* Introduce `pklJavaExecutable` plugin, which sets up building and publishing of executable JAR.
* Introduce `pklNativeExecutable` plugin, which sets up building and publishing of native executables.
* Introduce `NativeImageBuild` Gradle task, which knows how to build native-image executables.
* Introduce `ExecutableSpec` extension, for projects that publish executables to configure how those executables should be published.
* `./griddles buildNative`, by default, will only build the executable of the host OS/Arch, and will no longer cross-build.
* The target arch of `./gradlew buildNative` can be changed using `-Dpkl.targetArch=<aarch64|amd64>`.
* On linux/amd64 only, with `./gradlew buildNative`, a statically linked executable can be built using `-Dpkl.musl=true`
* Make `javaExecutable` a dependency of `assemble`
* Make `testStartJavaExecutable` a dependency of `check`
* Change name `pklNativeBuild` to `pklNativeLifecycle` to better match the plugin's purpose
* Remove Truffle SVM classes from main source set (don't publish these classes as part of the pkl-cli JAR)
* Change CircleCI definition to publish new executables
* Change CircleCI definition to call `buildNative` instead of individual task names
2025-03-19 09:08:12 -07:00
Islon Scherer
aad530b9a8 move parser out of pkl-core (#1024) 2025-03-18 20:23:53 +01:00
Islon Scherer
1cd0549bd6 remove stacking of block comments (#1022) 2025-03-12 18:24:38 +01:00
Kushal Pisavadia
8b7d59e4e4 Build with m2pro.large instances, not macos.m1.large.gen1 (#1020)
* Update `com.circleci.v2` to `1.5.0` and `pkl.impl.circleci` to `1.2.0`

See:
- https://github.com/apple/pkl-pantry/pull/103
- https://github.com/apple/pkl-project-commons/pull/7

* Build with `m2pro.large` instances, not `macos.m1.large.gen1`
2025-03-11 11:20:43 +01:00
Kushal Pisavadia
f7eaeddc78 Alphabetically sort the projects list in settings.gradle.kts (#1015) 2025-03-07 15:06:14 +01:00
Daniel Chao
18e7a7e87e Add optimization for generator bodies that don't introduce new members (#1013)
If a generator object literal doesn't add any object members, we
can simply use the parent in its place.

Co-authored-by: Kushal Pisavadia <kushi.p@gmail.com>
2025-03-05 10:25:54 -08:00
Daniel Chao
bf484b3431 Revert Gradle plugin tests to use deprecated API (#1011)
Using the replacement API fails with:
"DefaultTaskContainer#register(String, Class, Action) on task set cannot be executed in the current context."
2025-03-04 07:58:16 -08:00
Daniel Chao
5636fb55c4 Adjust installation docs (#1010) 2025-03-03 12:19:13 -08:00
Daniel Chao
5021107269 Update Gradle to 8.13 (#1008)
Also:

* Replace usages of deprecated APIs
* Prevent `testStart*` tasks from writing to standard output
2025-03-03 12:08:48 -08:00
Pedro Piñera Buendía
3baefbcfd3 Document how to install pkl with Mise (#982) 2025-03-03 12:01:09 -08:00
Daniel Chao
a0a64923a6 Cherry pick changes from 0.28.1 (#1004)
* Add release notes for 0.28.1
* Update Pkl version in jbang catalog
2025-03-03 10:18:35 -08:00
Daniel Chao
09166ba165 Allow native-image flags to be passed through from Gradle properties (#1001)
Allow other build environments (e.g. homebrew) to configure the native-image build without requiring source code changes.
2025-03-03 08:49:44 -08:00
Daniel Chao
9ba7fa01af Fix shadow jar logic (#998)
Fix an incorrect relocation setting.

Also, add tests to start the shadow jar, and also to test the shadow jar settings.
2025-03-03 07:48:35 -08:00
Daniel Chao
9f22c56ff5 Make Truffle use fallback runtime in Gradle plugin (#995)
Using native libraries in Gradle plugins is problematic; this adds some flags that causes Truffle to use a fallback runtime that avoids loading native libraries.
2025-02-27 12:54:49 -08:00
Daniel Chao
06d04878f7 Add Kotlin version bump to breaking changes (#987) 2025-02-26 14:06:06 -08:00
Islon Scherer
d3ba0f9e47 Start next dev iteration 2025-02-26 09:48:20 -08:00
Islon Scherer
cc9827f032 remove folders from build executable dir 2025-02-26 09:48:20 -08:00
Islon Scherer
d1f7b639a7 change version to 0.28.0 2025-02-26 09:48:20 -08:00
601 changed files with 9828 additions and 5467 deletions

View File

@@ -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,25 +81,30 @@ 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
}
}
}
}
@@ -147,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/*
"""#
}
}

View File

@@ -23,7 +23,7 @@ jobs:
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:macExecutableAmd64 pkl-core:testMacExecutableAmd64 pkl-server:testMacExecutableAmd64
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true -Dpkl.targetArch=amd64 pkl-cli:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
@@ -34,7 +34,7 @@ jobs:
environment:
LANG: en_US.UTF-8
JAVA_HOME: /Users/distiller/jdk/Contents/Home
resource_class: macos.m1.large.gen1
resource_class: m2pro.large
macos:
xcode: 15.3.0
pkl-cli-linux-amd64-release:
@@ -100,7 +100,7 @@ jobs:
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:linuxExecutableAmd64 pkl-core:testLinuxExecutableAmd64 pkl-server:testLinuxExecutableAmd64
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
@@ -131,7 +131,7 @@ jobs:
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:macExecutableAarch64 pkl-core:testMacExecutableAarch64 pkl-server:testMacExecutableAarch64
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
@@ -142,7 +142,7 @@ jobs:
environment:
LANG: en_US.UTF-8
JAVA_HOME: /Users/distiller/jdk/Contents/Home
resource_class: macos.m1.large.gen1
resource_class: m2pro.large
macos:
xcode: 15.3.0
pkl-cli-linux-aarch64-release:
@@ -192,7 +192,7 @@ jobs:
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:linuxExecutableAarch64 pkl-core:testLinuxExecutableAarch64 pkl-server:testLinuxExecutableAarch64
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
@@ -269,7 +269,7 @@ jobs:
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:alpineExecutableAmd64 pkl-core:testAlpineExecutableAmd64 pkl-server:testAlpineExecutableAmd64
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true -Dpkl.musl=true pkl-cli:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
@@ -301,7 +301,7 @@ jobs:
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:windowsExecutableAmd64 pkl-core:testWindowsExecutableAmd64 pkl-server:testWindowsExecutableAmd64
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:buildNative
name: gradle buildNative
shell: bash.exe
- persist_to_workspace:
@@ -316,6 +316,319 @@ jobs:
resource_class: windows.large
machine:
image: windows-server-2022-gui:current
pkl-doc-macOS-amd64-release:
steps:
- checkout
- run:
command: /usr/sbin/softwareupdate --install-rosetta --agree-to-license
name: Installing Rosetta 2
- run:
command: |-
# install jdk
curl -Lf \
https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B11/OpenJDK21U-jdk_x64_mac_hotspot_21.0.5_11.tar.gz -o /tmp/jdk.tar.gz
mkdir $HOME/jdk \
&& cd $HOME/jdk \
&& cat /tmp/jdk.tar.gz | tar --strip-components=1 -xzC .
name: Set up environment
shell: '#!/bin/bash -exo pipefail'
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true -Dpkl.targetArch=amd64 pkl-doc:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-doc/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
JAVA_HOME: /Users/distiller/jdk/Contents/Home
resource_class: macos.m1.large.gen1
macos:
xcode: 15.3.0
pkl-doc-linux-amd64-release:
steps:
- checkout
- restore_cache:
key: staticdeps-amd64
name: Restore static deps from cache
- run:
command: |-
sed -ie '/\[ol8_codeready_builder\]/,/^$/s/enabled=0/enabled=1/g' /etc/yum.repos.d/oracle-linux-ol8.repo \
&& microdnf -y install util-linux tree coreutils-single findutils curl tar gzip git zlib-devel gcc-c++ make openssl glibc-langpack-en libstdc++-static \
&& microdnf clean all \
&& rm -rf /var/cache/dnf
# install jdk
curl -Lf \
https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B11/OpenJDK21U-jdk_x64_linux_hotspot_21.0.5_11.tar.gz -o /tmp/jdk.tar.gz
mkdir /jdk \
&& cd /jdk \
&& cat /tmp/jdk.tar.gz | tar --strip-components=1 -xzC .
mkdir -p ~/staticdeps/bin
cp /usr/lib/gcc/x86_64-redhat-linux/8/libstdc++.a ~/staticdeps
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
curl -Lf https://github.com/madler/zlib/releases/download/v1.2.13/zlib-1.2.13.tar.gz -o /tmp/zlib.tar.gz
mkdir -p /tmp/dep_zlib-1.2.13 \
&& cd /tmp/dep_zlib-1.2.13 \
&& cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC . \
&& echo "zlib-1.2.13: configure..." && ./configure --static --prefix="$HOME"/staticdeps > /dev/null \
&& echo "zlib-1.2.13: make..." && make -s -j4 \
&& echo "zlib-1.2.13: make install..." && make -s install \
&& rm -rf /tmp/dep_zlib-1.2.13
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
curl -Lf https://musl.libc.org/releases/musl-1.2.2.tar.gz -o /tmp/musl.tar.gz
mkdir -p /tmp/dep_musl-1.2.2 \
&& cd /tmp/dep_musl-1.2.2 \
&& cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC . \
&& echo "musl-1.2.2: configure..." && ./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null \
&& echo "musl-1.2.2: make..." && make -s -j4 \
&& echo "musl-1.2.2: make install..." && make -s install \
&& rm -rf /tmp/dep_musl-1.2.2
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
name: Set up environment
shell: '#!/bin/bash -exo pipefail'
- save_cache:
paths:
- ~/staticdeps
key: staticdeps-amd64
name: Save statics deps to cache
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-doc/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
resource_class: xlarge
docker:
- image: oraclelinux:8-slim
pkl-doc-macOS-aarch64-release:
steps:
- checkout
- run:
command: |-
# install jdk
curl -Lf \
https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B11/OpenJDK21U-jdk_aarch64_mac_hotspot_21.0.5_11.tar.gz -o /tmp/jdk.tar.gz
mkdir $HOME/jdk \
&& cd $HOME/jdk \
&& cat /tmp/jdk.tar.gz | tar --strip-components=1 -xzC .
name: Set up environment
shell: '#!/bin/bash -exo pipefail'
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-doc/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
JAVA_HOME: /Users/distiller/jdk/Contents/Home
resource_class: macos.m1.large.gen1
macos:
xcode: 15.3.0
pkl-doc-linux-aarch64-release:
steps:
- checkout
- restore_cache:
key: staticdeps-aarch64
name: Restore static deps from cache
- run:
command: |-
sed -ie '/\[ol8_codeready_builder\]/,/^$/s/enabled=0/enabled=1/g' /etc/yum.repos.d/oracle-linux-ol8.repo \
&& microdnf -y install util-linux tree coreutils-single findutils curl tar gzip git zlib-devel gcc-c++ make openssl glibc-langpack-en libstdc++-static \
&& microdnf clean all \
&& rm -rf /var/cache/dnf
# install jdk
curl -Lf \
https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B11/OpenJDK21U-jdk_aarch64_linux_hotspot_21.0.5_11.tar.gz -o /tmp/jdk.tar.gz
mkdir /jdk \
&& cd /jdk \
&& cat /tmp/jdk.tar.gz | tar --strip-components=1 -xzC .
mkdir -p ~/staticdeps/bin
cp /usr/lib/gcc/aarch64-redhat-linux/8/libstdc++.a ~/staticdeps
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
curl -Lf https://github.com/madler/zlib/releases/download/v1.2.13/zlib-1.2.13.tar.gz -o /tmp/zlib.tar.gz
mkdir -p /tmp/dep_zlib-1.2.13 \
&& cd /tmp/dep_zlib-1.2.13 \
&& cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC . \
&& echo "zlib-1.2.13: configure..." && ./configure --static --prefix="$HOME"/staticdeps > /dev/null \
&& echo "zlib-1.2.13: make..." && make -s -j4 \
&& echo "zlib-1.2.13: make install..." && make -s install \
&& rm -rf /tmp/dep_zlib-1.2.13
fi
name: Set up environment
shell: '#!/bin/bash -exo pipefail'
- save_cache:
paths:
- ~/staticdeps
key: staticdeps-aarch64
name: Save statics deps to cache
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-doc/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
resource_class: arm.xlarge
docker:
- image: arm64v8/oraclelinux:8-slim
pkl-doc-linux-alpine-amd64-release:
steps:
- checkout
- restore_cache:
key: staticdeps-amd64
name: Restore static deps from cache
- run:
command: |-
sed -ie '/\[ol8_codeready_builder\]/,/^$/s/enabled=0/enabled=1/g' /etc/yum.repos.d/oracle-linux-ol8.repo \
&& microdnf -y install util-linux tree coreutils-single findutils curl tar gzip git zlib-devel gcc-c++ make openssl glibc-langpack-en libstdc++-static \
&& microdnf clean all \
&& rm -rf /var/cache/dnf
# install jdk
curl -Lf \
https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B11/OpenJDK21U-jdk_x64_linux_hotspot_21.0.5_11.tar.gz -o /tmp/jdk.tar.gz
mkdir /jdk \
&& cd /jdk \
&& cat /tmp/jdk.tar.gz | tar --strip-components=1 -xzC .
mkdir -p ~/staticdeps/bin
cp /usr/lib/gcc/x86_64-redhat-linux/8/libstdc++.a ~/staticdeps
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
curl -Lf https://github.com/madler/zlib/releases/download/v1.2.13/zlib-1.2.13.tar.gz -o /tmp/zlib.tar.gz
mkdir -p /tmp/dep_zlib-1.2.13 \
&& cd /tmp/dep_zlib-1.2.13 \
&& cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC . \
&& echo "zlib-1.2.13: configure..." && ./configure --static --prefix="$HOME"/staticdeps > /dev/null \
&& echo "zlib-1.2.13: make..." && make -s -j4 \
&& echo "zlib-1.2.13: make install..." && make -s install \
&& rm -rf /tmp/dep_zlib-1.2.13
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
curl -Lf https://musl.libc.org/releases/musl-1.2.2.tar.gz -o /tmp/musl.tar.gz
mkdir -p /tmp/dep_musl-1.2.2 \
&& cd /tmp/dep_musl-1.2.2 \
&& cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC . \
&& echo "musl-1.2.2: configure..." && ./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null \
&& echo "musl-1.2.2: make..." && make -s -j4 \
&& echo "musl-1.2.2: make install..." && make -s install \
&& rm -rf /tmp/dep_musl-1.2.2
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
name: Set up environment
shell: '#!/bin/bash -exo pipefail'
- save_cache:
paths:
- ~/staticdeps
key: staticdeps-amd64
name: Save statics deps to cache
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true -Dpkl.musl=true pkl-doc:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-doc/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
resource_class: xlarge
docker:
- image: oraclelinux:8-slim
pkl-doc-windows-amd64-release:
steps:
- checkout
- run:
command: |-
# install jdk
curl -Lf \
https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B11/OpenJDK21U-jdk_x64_windows_hotspot_21.0.5_11.zip -o /tmp/jdk.zip
unzip /tmp/jdk.zip -d /tmp/jdk \
&& cd /tmp/jdk/jdk-* \
&& mkdir /jdk \
&& cp -r . /jdk
name: Set up environment
shell: bash.exe
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:buildNative
name: gradle buildNative
shell: bash.exe
- persist_to_workspace:
root: '.'
paths:
- pkl-doc/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
resource_class: windows.large
machine:
image: windows-server-2022-gui:current
pkl-cli-macOS-amd64-snapshot:
steps:
- checkout
@@ -336,7 +649,7 @@ jobs:
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-cli:macExecutableAmd64 pkl-core:testMacExecutableAmd64 pkl-server:testMacExecutableAmd64
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -Dpkl.targetArch=amd64 pkl-cli:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
@@ -347,7 +660,7 @@ jobs:
environment:
LANG: en_US.UTF-8
JAVA_HOME: /Users/distiller/jdk/Contents/Home
resource_class: macos.m1.large.gen1
resource_class: m2pro.large
macos:
xcode: 15.3.0
pkl-cli-linux-amd64-snapshot:
@@ -413,7 +726,7 @@ jobs:
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-cli:linuxExecutableAmd64 pkl-core:testLinuxExecutableAmd64 pkl-server:testLinuxExecutableAmd64
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-cli:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
@@ -444,7 +757,7 @@ jobs:
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-cli:macExecutableAarch64 pkl-core:testMacExecutableAarch64 pkl-server:testMacExecutableAarch64
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-cli:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
@@ -455,7 +768,7 @@ jobs:
environment:
LANG: en_US.UTF-8
JAVA_HOME: /Users/distiller/jdk/Contents/Home
resource_class: macos.m1.large.gen1
resource_class: m2pro.large
macos:
xcode: 15.3.0
pkl-cli-linux-aarch64-snapshot:
@@ -505,7 +818,7 @@ jobs:
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-cli:linuxExecutableAarch64 pkl-core:testLinuxExecutableAarch64 pkl-server:testLinuxExecutableAarch64
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-cli:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
@@ -582,7 +895,7 @@ jobs:
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-cli:alpineExecutableAmd64 pkl-core:testAlpineExecutableAmd64 pkl-server:testAlpineExecutableAmd64
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-cli:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
@@ -614,7 +927,7 @@ jobs:
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-cli:windowsExecutableAmd64 pkl-core:testWindowsExecutableAmd64 pkl-server:testWindowsExecutableAmd64
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-cli:buildNative
name: gradle buildNative
shell: bash.exe
- persist_to_workspace:
@@ -629,6 +942,319 @@ jobs:
resource_class: windows.large
machine:
image: windows-server-2022-gui:current
pkl-doc-macOS-amd64-snapshot:
steps:
- checkout
- run:
command: /usr/sbin/softwareupdate --install-rosetta --agree-to-license
name: Installing Rosetta 2
- run:
command: |-
# install jdk
curl -Lf \
https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B11/OpenJDK21U-jdk_x64_mac_hotspot_21.0.5_11.tar.gz -o /tmp/jdk.tar.gz
mkdir $HOME/jdk \
&& cd $HOME/jdk \
&& cat /tmp/jdk.tar.gz | tar --strip-components=1 -xzC .
name: Set up environment
shell: '#!/bin/bash -exo pipefail'
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -Dpkl.targetArch=amd64 pkl-doc:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-doc/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
JAVA_HOME: /Users/distiller/jdk/Contents/Home
resource_class: macos.m1.large.gen1
macos:
xcode: 15.3.0
pkl-doc-linux-amd64-snapshot:
steps:
- checkout
- restore_cache:
key: staticdeps-amd64
name: Restore static deps from cache
- run:
command: |-
sed -ie '/\[ol8_codeready_builder\]/,/^$/s/enabled=0/enabled=1/g' /etc/yum.repos.d/oracle-linux-ol8.repo \
&& microdnf -y install util-linux tree coreutils-single findutils curl tar gzip git zlib-devel gcc-c++ make openssl glibc-langpack-en libstdc++-static \
&& microdnf clean all \
&& rm -rf /var/cache/dnf
# install jdk
curl -Lf \
https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B11/OpenJDK21U-jdk_x64_linux_hotspot_21.0.5_11.tar.gz -o /tmp/jdk.tar.gz
mkdir /jdk \
&& cd /jdk \
&& cat /tmp/jdk.tar.gz | tar --strip-components=1 -xzC .
mkdir -p ~/staticdeps/bin
cp /usr/lib/gcc/x86_64-redhat-linux/8/libstdc++.a ~/staticdeps
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
curl -Lf https://github.com/madler/zlib/releases/download/v1.2.13/zlib-1.2.13.tar.gz -o /tmp/zlib.tar.gz
mkdir -p /tmp/dep_zlib-1.2.13 \
&& cd /tmp/dep_zlib-1.2.13 \
&& cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC . \
&& echo "zlib-1.2.13: configure..." && ./configure --static --prefix="$HOME"/staticdeps > /dev/null \
&& echo "zlib-1.2.13: make..." && make -s -j4 \
&& echo "zlib-1.2.13: make install..." && make -s install \
&& rm -rf /tmp/dep_zlib-1.2.13
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
curl -Lf https://musl.libc.org/releases/musl-1.2.2.tar.gz -o /tmp/musl.tar.gz
mkdir -p /tmp/dep_musl-1.2.2 \
&& cd /tmp/dep_musl-1.2.2 \
&& cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC . \
&& echo "musl-1.2.2: configure..." && ./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null \
&& echo "musl-1.2.2: make..." && make -s -j4 \
&& echo "musl-1.2.2: make install..." && make -s install \
&& rm -rf /tmp/dep_musl-1.2.2
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
name: Set up environment
shell: '#!/bin/bash -exo pipefail'
- save_cache:
paths:
- ~/staticdeps
key: staticdeps-amd64
name: Save statics deps to cache
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-doc:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-doc/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
resource_class: xlarge
docker:
- image: oraclelinux:8-slim
pkl-doc-macOS-aarch64-snapshot:
steps:
- checkout
- run:
command: |-
# install jdk
curl -Lf \
https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B11/OpenJDK21U-jdk_aarch64_mac_hotspot_21.0.5_11.tar.gz -o /tmp/jdk.tar.gz
mkdir $HOME/jdk \
&& cd $HOME/jdk \
&& cat /tmp/jdk.tar.gz | tar --strip-components=1 -xzC .
name: Set up environment
shell: '#!/bin/bash -exo pipefail'
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-doc:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-doc/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
JAVA_HOME: /Users/distiller/jdk/Contents/Home
resource_class: macos.m1.large.gen1
macos:
xcode: 15.3.0
pkl-doc-linux-aarch64-snapshot:
steps:
- checkout
- restore_cache:
key: staticdeps-aarch64
name: Restore static deps from cache
- run:
command: |-
sed -ie '/\[ol8_codeready_builder\]/,/^$/s/enabled=0/enabled=1/g' /etc/yum.repos.d/oracle-linux-ol8.repo \
&& microdnf -y install util-linux tree coreutils-single findutils curl tar gzip git zlib-devel gcc-c++ make openssl glibc-langpack-en libstdc++-static \
&& microdnf clean all \
&& rm -rf /var/cache/dnf
# install jdk
curl -Lf \
https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B11/OpenJDK21U-jdk_aarch64_linux_hotspot_21.0.5_11.tar.gz -o /tmp/jdk.tar.gz
mkdir /jdk \
&& cd /jdk \
&& cat /tmp/jdk.tar.gz | tar --strip-components=1 -xzC .
mkdir -p ~/staticdeps/bin
cp /usr/lib/gcc/aarch64-redhat-linux/8/libstdc++.a ~/staticdeps
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
curl -Lf https://github.com/madler/zlib/releases/download/v1.2.13/zlib-1.2.13.tar.gz -o /tmp/zlib.tar.gz
mkdir -p /tmp/dep_zlib-1.2.13 \
&& cd /tmp/dep_zlib-1.2.13 \
&& cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC . \
&& echo "zlib-1.2.13: configure..." && ./configure --static --prefix="$HOME"/staticdeps > /dev/null \
&& echo "zlib-1.2.13: make..." && make -s -j4 \
&& echo "zlib-1.2.13: make install..." && make -s install \
&& rm -rf /tmp/dep_zlib-1.2.13
fi
name: Set up environment
shell: '#!/bin/bash -exo pipefail'
- save_cache:
paths:
- ~/staticdeps
key: staticdeps-aarch64
name: Save statics deps to cache
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-doc:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-doc/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
resource_class: arm.xlarge
docker:
- image: arm64v8/oraclelinux:8-slim
pkl-doc-linux-alpine-amd64-snapshot:
steps:
- checkout
- restore_cache:
key: staticdeps-amd64
name: Restore static deps from cache
- run:
command: |-
sed -ie '/\[ol8_codeready_builder\]/,/^$/s/enabled=0/enabled=1/g' /etc/yum.repos.d/oracle-linux-ol8.repo \
&& microdnf -y install util-linux tree coreutils-single findutils curl tar gzip git zlib-devel gcc-c++ make openssl glibc-langpack-en libstdc++-static \
&& microdnf clean all \
&& rm -rf /var/cache/dnf
# install jdk
curl -Lf \
https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B11/OpenJDK21U-jdk_x64_linux_hotspot_21.0.5_11.tar.gz -o /tmp/jdk.tar.gz
mkdir /jdk \
&& cd /jdk \
&& cat /tmp/jdk.tar.gz | tar --strip-components=1 -xzC .
mkdir -p ~/staticdeps/bin
cp /usr/lib/gcc/x86_64-redhat-linux/8/libstdc++.a ~/staticdeps
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
curl -Lf https://github.com/madler/zlib/releases/download/v1.2.13/zlib-1.2.13.tar.gz -o /tmp/zlib.tar.gz
mkdir -p /tmp/dep_zlib-1.2.13 \
&& cd /tmp/dep_zlib-1.2.13 \
&& cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC . \
&& echo "zlib-1.2.13: configure..." && ./configure --static --prefix="$HOME"/staticdeps > /dev/null \
&& echo "zlib-1.2.13: make..." && make -s -j4 \
&& echo "zlib-1.2.13: make install..." && make -s install \
&& rm -rf /tmp/dep_zlib-1.2.13
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
curl -Lf https://musl.libc.org/releases/musl-1.2.2.tar.gz -o /tmp/musl.tar.gz
mkdir -p /tmp/dep_musl-1.2.2 \
&& cd /tmp/dep_musl-1.2.2 \
&& cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC . \
&& echo "musl-1.2.2: configure..." && ./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null \
&& echo "musl-1.2.2: make..." && make -s -j4 \
&& echo "musl-1.2.2: make install..." && make -s install \
&& rm -rf /tmp/dep_musl-1.2.2
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
name: Set up environment
shell: '#!/bin/bash -exo pipefail'
- save_cache:
paths:
- ~/staticdeps
key: staticdeps-amd64
name: Save statics deps to cache
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-doc:buildNative
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-doc/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
resource_class: xlarge
docker:
- image: oraclelinux:8-slim
pkl-doc-windows-amd64-snapshot:
steps:
- checkout
- run:
command: |-
# install jdk
curl -Lf \
https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B11/OpenJDK21U-jdk_x64_windows_hotspot_21.0.5_11.zip -o /tmp/jdk.zip
unzip /tmp/jdk.zip -d /tmp/jdk \
&& cd /tmp/jdk/jdk-* \
&& mkdir /jdk \
&& cp -r . /jdk
name: Set up environment
shell: bash.exe
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DpklMultiJdkTesting=true pkl-doc:buildNative
name: gradle buildNative
shell: bash.exe
- persist_to_workspace:
root: '.'
paths:
- pkl-doc/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
resource_class: windows.large
machine:
image: windows-server-2022-gui:current
gradle-check:
steps:
- checkout
@@ -704,6 +1330,9 @@ jobs:
root: '.'
paths:
- pkl-cli/build/executable/
- pkl-doc/build/executable/
- pkl-codegen-java/build/executable/
- pkl-codegen-kotlin/build/executable/
- store_test_results:
path: ~/test-results
environment:
@@ -721,6 +1350,9 @@ jobs:
root: '.'
paths:
- pkl-cli/build/executable/
- pkl-doc/build/executable/
- pkl-codegen-java/build/executable/
- pkl-codegen-kotlin/build/executable/
- store_test_results:
path: ~/test-results
environment:
@@ -734,14 +1366,15 @@ jobs:
- run:
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/*
name: Publish release on GitHub
docker:
- image: maniator/gh:v2.40.1
@@ -800,6 +1433,12 @@ workflows:
- pkl-cli-linux-aarch64-snapshot
- pkl-cli-linux-alpine-amd64-snapshot
- pkl-cli-windows-amd64-snapshot
- pkl-doc-macOS-amd64-snapshot
- pkl-doc-linux-amd64-snapshot
- pkl-doc-macOS-aarch64-snapshot
- pkl-doc-linux-aarch64-snapshot
- pkl-doc-linux-alpine-amd64-snapshot
- pkl-doc-windows-amd64-snapshot
- deploy-snapshot:
requires:
- gradle-check
@@ -812,6 +1451,12 @@ workflows:
- pkl-cli-linux-aarch64-snapshot
- pkl-cli-linux-alpine-amd64-snapshot
- pkl-cli-windows-amd64-snapshot
- pkl-doc-macOS-amd64-snapshot
- pkl-doc-linux-amd64-snapshot
- pkl-doc-macOS-aarch64-snapshot
- pkl-doc-linux-aarch64-snapshot
- pkl-doc-linux-alpine-amd64-snapshot
- pkl-doc-windows-amd64-snapshot
context: pkl-maven-release
- trigger-docsite-build:
requires:
@@ -884,6 +1529,42 @@ workflows:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- pkl-doc-macOS-amd64-release:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- pkl-doc-linux-amd64-release:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- pkl-doc-macOS-aarch64-release:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- pkl-doc-linux-aarch64-release:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- pkl-doc-linux-alpine-amd64-release:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- pkl-doc-windows-amd64-release:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- github-release:
requires:
- gradle-check
@@ -896,6 +1577,12 @@ workflows:
- pkl-cli-linux-aarch64-release
- pkl-cli-linux-alpine-amd64-release
- pkl-cli-windows-amd64-release
- pkl-doc-macOS-amd64-release
- pkl-doc-linux-amd64-release
- pkl-doc-macOS-aarch64-release
- pkl-doc-linux-aarch64-release
- pkl-doc-linux-alpine-amd64-release
- pkl-doc-windows-amd64-release
context: pkl-github-release
filters:
branches:
@@ -933,6 +1620,12 @@ workflows:
- pkl-cli-linux-aarch64-release
- pkl-cli-linux-alpine-amd64-release
- pkl-cli-windows-amd64-release
- pkl-doc-macOS-amd64-release
- pkl-doc-linux-amd64-release
- pkl-doc-macOS-aarch64-release
- pkl-doc-linux-aarch64-release
- pkl-doc-linux-alpine-amd64-release
- pkl-doc-windows-amd64-release
when:
matches:
value: << pipeline.git.branch >>

View File

@@ -16,7 +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/com.circleci.v2@1.5.0#/Config.pkl"
/// The architecture to use
arch: "amd64"|"aarch64"
@@ -24,8 +24,20 @@ 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 (muslVersion = "1.2.2")
let (zlibVersion = "1.2.13")
@@ -131,24 +143,18 @@ steps {
}
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/"
}
}
}
@@ -158,7 +164,7 @@ job {
macos {
xcode = "15.3.0"
}
resource_class = "macos.m1.large.gen1"
resource_class = "m2pro.large"
environment {
["JAVA_HOME"] = "/Users/distiller/jdk/Contents/Home"
}

View File

@@ -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"
local self = this
@@ -30,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/"
}
}
}

View File

@@ -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"
steps {
new Config.RunStep {

View File

@@ -15,7 +15,7 @@
//===----------------------------------------------------------------------===//
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.
@@ -51,8 +51,11 @@ fixed gradleArgs = new Listing {
when (isRelease) {
"-DreleaseBuild=true"
}
...extraGradleArgs
}.join(" ")
extraGradleArgs: Listing<String>
steps: Listing<Config.Step>
job: Config.Job = new {

View File

@@ -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

4
.gitignore vendored
View File

@@ -20,8 +20,4 @@ testgenerated/
.pkl-lsp/
# :pkl-core:makeIntelliJAntlrPluginHappy
gen/
PklLexer.tokens
.kotlin/

2
.mailmap Normal file
View File

@@ -0,0 +1,2 @@
Jen Basch <421772+HT154@users.noreply.github.com>
Jen Basch <jbasch@apple.com>

View File

@@ -45,12 +45,11 @@ install {uri-native-prerequisites-windows}[Prerequisites For Native Image on Win
[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 native executable(s) for current platform
# (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-aarch64 # run Mac executable
@@ -83,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:generateTestGrammarSource`
** Output dir is `testgenerated/antlr/`
== Remote JVM Debugging

View File

@@ -25,6 +25,7 @@ val graal: Configuration by configurations.creating
dependencies {
jmh(projects.pklCore)
jmh(projects.pklCommonsTest)
jmh(projects.pklParser)
truffle(libs.truffleApi)
graal(libs.graalCompiler)
}

View File

@@ -4,7 +4,7 @@
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=jmhCompileClasspath,jmhImplementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata,testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,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
@@ -25,38 +25,30 @@ org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=kotlinBuildToolsApiClasspat
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,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
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,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath,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,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath,testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-api:5.11.4=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-api:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:5.11.4=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-engine:5.8.2=testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.11.4=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.platform:junit-platform-commons:1.11.4=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.platform:junit-platform-commons:1.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.platform:junit-platform-engine:1.11.4=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.platform:junit-platform-engine:1.8.2=testJdk17RuntimeClasspath
org.junit.platform:junit-platform-launcher:1.8.2=testJdk17RuntimeClasspath
org.junit:junit-bom:5.11.4=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit:junit-bom:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
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.2.0=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.opentest4j:opentest4j:1.3.0=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,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.9=jmh,jmhRuntimeClasspath
empty=annotationProcessor,apiDependenciesMetadata,compileClasspath,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,jmhAnnotationProcessor,jmhApiDependenciesMetadata,jmhCompileOnlyDependenciesMetadata,jmhIntransitiveDependenciesMetadata,jmhKotlinScriptDef,jmhKotlinScriptDefExtensions,jmhRuntimeOnlyDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtimeClasspath,runtimeOnlyDependenciesMetadata,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testJdk17AnnotationProcessor,testJdk17ApiDependenciesMetadata,testJdk17CompileOnlyDependenciesMetadata,testJdk17IntransitiveDependenciesMetadata,testJdk17KotlinScriptDefExtensions,testKotlinScriptDef,testKotlinScriptDefExtensions
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

View File

@@ -24,6 +24,8 @@ 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)

View File

@@ -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.
@@ -19,7 +19,6 @@
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
@@ -33,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/"))
}
}
}
@@ -48,9 +47,6 @@ idea {
delegateBuildRunToGradle = true
testRunner = PLATFORM
}
configure<TaskTriggersConfig> {
afterSync(provider { project(":pkl-core").tasks.named("makeIntelliJAntlrPluginHappy") })
}
}
}
}

View File

@@ -35,16 +35,18 @@ dependencies {
}
java {
sourceCompatibility = JavaVersion.toVersion(toolchainVersion)
targetCompatibility = JavaVersion.toVersion(toolchainVersion)
toolchain {
languageVersion = JavaLanguageVersion.of(toolchainVersion)
vendor = JvmVendorSpec.ADOPTIUM
}
}
tasks.withType<JavaCompile>().configureEach { options.release = toolchainVersion }
kotlin {
jvmToolchain(toolchainVersion)
compilerOptions { jvmTarget = JvmTarget.fromTarget(toolchainVersion.toString()) }
compilerOptions {
jvmTarget = JvmTarget.fromTarget(toolchainVersion.toString())
freeCompilerArgs.add("-Xjdk-release=$toolchainVersion")
}
}

View File

@@ -20,8 +20,6 @@ import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.api.attributes.Category
import org.gradle.api.plugins.JvmTestSuitePlugin
import org.gradle.api.plugins.jvm.JvmTestSuite
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.testing.Test
@@ -30,7 +28,6 @@ import org.gradle.jvm.toolchain.*
import org.gradle.kotlin.dsl.*
import org.gradle.kotlin.dsl.support.serviceOf
import org.gradle.process.CommandLineArgumentProvider
import org.gradle.testing.base.TestingExtension
/**
* JVM bytecode target; this is pinned at a reasonable version, because downstream JVM projects
@@ -107,6 +104,18 @@ open class BuildInfo(private val project: Project) {
}
}
/** 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")) {
@@ -198,10 +207,18 @@ open class BuildInfo(private val project: Project) {
// 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).filter { version ->
// unless we are instructed to test all JDKs, tests only include LTS releases and
// versions above the toolchain version.
testAllJdks || (JavaVersionRange.isLTS(version) || version >= jdkToolchainVersion)
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
}
}
@@ -240,9 +257,6 @@ open class BuildInfo(private val project: Project) {
configurator: MultiJdkTestConfigurator = {},
): Iterable<Provider<out Any>> =
with(project) {
// force the `jvm-test-suite` plugin to apply first
project.pluginManager.apply(JvmTestSuitePlugin::class.java)
val isMultiVendor = testJdkVendors.count() > 1
val baseNameProvider = { templateTask.get().name }
val namer = testNamer(baseNameProvider)
@@ -275,13 +289,6 @@ open class BuildInfo(private val project: Project) {
// multiply out by jdk vendor
testJdkVendors.map { vendor -> (targetVersion to vendor) }
}
.filter { (jdkTarget, vendor) ->
// only include experimental tasks in the return suite if the flag is set. if the task
// is withheld from the returned list, it will not be executed by default with `gradle
// check`.
testExperimentalJdks ||
(!namer(jdkTarget, vendor.takeIf { isMultiVendor }).contains("Experimental"))
}
.map { (jdkTarget, vendor) ->
if (jdkToolchainVersion == jdkTarget)
tasks.register(namer(jdkTarget, vendor)) {
@@ -292,25 +299,18 @@ open class BuildInfo(private val project: Project) {
"Alias for regular '${baseNameProvider()}' task, on JDK ${jdkTarget.asInt()}"
}
else
the<TestingExtension>().suites.register(
namer(jdkTarget, vendor.takeIf { isMultiVendor }),
JvmTestSuite::class,
) {
targets.all {
testTask.configure {
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") }
}
)
}
}
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()
@@ -330,9 +330,8 @@ open class BuildInfo(private val project: Project) {
}
val multiJdkTesting: Boolean by lazy {
// By default, Pkl is tested against a full range of JDK versions, past and present, within the
// supported bounds of `PKL_TEST_JDK_TARGET` and `PKL_TEST_JDK_MAXIMUM`. To opt-out of this
// behavior, set `-DpklMultiJdkTesting=false` on the Gradle command line.
// 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.

View 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>
}

View 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)
}
}
}
}

View File

@@ -16,7 +16,7 @@
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.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
plugins { id("com.diffplug.spotless") }
@@ -52,15 +52,14 @@ configurations.all {
}
plugins.withType(JavaPlugin::class).configureEach {
val java = project.extensions.getByType<JavaPluginExtension>()
java.sourceCompatibility = JavaVersion.VERSION_17
java.targetCompatibility = JavaVersion.VERSION_17
tasks.withType<JavaCompile>().configureEach { options.release = 17 }
}
tasks.withType<KotlinCompile>().configureEach {
tasks.withType<KotlinJvmCompile>().configureEach {
compilerOptions {
jvmTarget = JvmTarget.JVM_17
freeCompilerArgs.addAll("-Xjsr305=strict", "-Xjvm-default=all")
freeCompilerArgs.add("-Xjdk-release=17")
}
}

View File

@@ -42,20 +42,20 @@ val relocations =
"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",
"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.",
"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",
"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",
"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.",
@@ -71,6 +71,19 @@ val relocations =
"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 {
@@ -103,9 +116,6 @@ tasks.shadowJar {
JavaVersionRange.startingAt(JavaLanguageVersion.of(minimumJvmTarget.majorVersion.toInt() + 1))
.forEach { exclude("META-INF/versions/${it.asInt()}/**") }
// org.antlr.v4.runtime.misc.RuleDependencyProcessor
exclude("META-INF/services/javax.annotation.processing.Processor")
exclude("module-info.*")
for ((from, to) in relocations) {

View 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"]) } }

View File

@@ -20,6 +20,7 @@ import org.gradle.accessors.dm.LibrariesForLibs
plugins {
`java-library`
`jvm-toolchains`
`jvm-test-suite`
id("pklKotlinTest")
id("com.diffplug.spotless")
}
@@ -34,14 +35,9 @@ val libs = the<LibrariesForLibs>()
val info = project.extensions.getByType<BuildInfo>()
java {
val jvmTarget = JavaVersion.toVersion(info.jvmTarget)
withSourcesJar() // creates `sourcesJar` task
withJavadocJar()
sourceCompatibility = jvmTarget
targetCompatibility = jvmTarget
toolchain {
languageVersion = info.jdkToolchainVersion
vendor = info.jdkVendor
@@ -112,10 +108,8 @@ tasks.compileJava {
}
tasks.withType<JavaCompile>().configureEach {
val jvmTarget = JavaVersion.toVersion(info.jvmTarget)
javaCompiler = info.javaCompiler
sourceCompatibility = jvmTarget.majorVersion
targetCompatibility = jvmTarget.majorVersion
options.release = info.jvmTarget
}
tasks.withType<JavaExec>().configureEach { jvmArgs(info.jpmsAddModulesFlags) }
@@ -142,4 +136,4 @@ tasks.test { configureJdkTestTask(info.javaTestLauncher) }
// inherits the configuration of the default `test` task (aside from an overridden launcher).
val jdkTestTasks = info.multiJdkTestingWith(tasks.test) { (_, jdk) -> configureJdkTestTask(jdk) }
if (info.multiJdkTesting) tasks.check { dependsOn(jdkTestTasks) }
tasks.check { dependsOn(jdkTestTasks) }

View File

@@ -42,5 +42,8 @@ tasks.compileKotlin {
}
tasks.withType<KotlinJvmCompile>().configureEach {
compilerOptions { jvmTarget = JvmTarget.fromTarget(buildInfo.jvmTarget.toString()) }
compilerOptions {
jvmTarget = JvmTarget.fromTarget(buildInfo.jvmTarget.toString())
freeCompilerArgs.addAll("-Xjdk-release=${buildInfo.jvmTarget}")
}
}

View File

@@ -14,6 +14,7 @@
* limitations under the License.
*/
import java.net.URI
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
plugins {
@@ -23,13 +24,16 @@ plugins {
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 {

View 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"])
}
}

View 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)
}

View File

@@ -1,6 +1,6 @@
name: main
title: Main Project
version: 0.28.0-dev
prerelease: true
version: 0.29.1
prerelease: false
nav:
- nav.adoc

View File

@@ -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.
@@ -37,8 +37,8 @@ dependencies {
testImplementation(projects.pklConfigJava)
testImplementation(projects.pklConfigKotlin)
testImplementation(projects.pklCommonsTest)
testImplementation(projects.pklParser)
testImplementation(libs.junitEngine)
testImplementation(libs.antlrRuntime)
}
tasks.test {

View File

@@ -1,10 +1,9 @@
# 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.16=testRuntimeClasspath
net.bytebuddy:byte-buddy:1.15.11=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
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
@@ -33,14 +32,15 @@ org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.0.21=testCompileClasspath,testImplemen
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.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-engine:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-params:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.platform:junit-platform-commons:1.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.platform:junit-platform-engine:1.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit:junit-bom:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
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,testRuntimeOnlyDependenciesMetadata
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.organicdesign:Paguro:3.10.3=testRuntimeClasspath
org.snakeyaml:snakeyaml-engine:2.9=testRuntimeClasspath
empty=annotationProcessor,apiDependenciesMetadata,compileClasspath,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtimeClasspath,runtimeOnlyDependenciesMetadata,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDef,testKotlinScriptDefExtensions
org.snakeyaml:snakeyaml-engine:2.10=testRuntimeClasspath
empty=annotationProcessor,apiDependenciesMetadata,compileClasspath,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,runtimeClasspath,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions

View File

@@ -7,7 +7,7 @@
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 Evolutiuon].
Pkl has a process for managing such designs in a repository called {uri-pkl-evolution}[Pkl Evolution].
== Roadmap
@@ -17,4 +17,4 @@ 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.
Additionally, as priorities change, it is possible that items can be moved around or backlogged.

View File

@@ -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.28.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::[]
@@ -75,11 +75,13 @@ endif::[]
: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
@@ -138,10 +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}

View File

@@ -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]]

View File

@@ -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
@@ -425,14 +426,12 @@ requestId: Int
evaluatorId: Int
/// The contents of the resource.
contents: Binary? // <1>
contents: Bytes? // <1>
/// 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

View File

@@ -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() {

View File

@@ -2,6 +2,12 @@
include::ROOT:partial$component-attributes.adoc[]
: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.
The benefits of code generation are:
@@ -27,7 +33,7 @@ The `pkl-codegen-java` library is available {uri-pkl-codegen-java-maven-module}[
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.
@@ -180,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.

View File

@@ -29,6 +29,13 @@ Default: (not set) +
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
[%collapsible]
====

View File

@@ -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() {

View File

@@ -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.
@@ -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.

View File

@@ -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

View File

@@ -1059,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}]
@@ -2154,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+`
@@ -3204,7 +3207,8 @@ This section discusses language features that are generally more relevant to tem
<<reserved-keywords,Reserved Keywords>> +
<<blank-identifiers,Blank Identifiers>> +
<<projects,Projects>> +
<<external-readers,External Readers>>
<<external-readers,External Readers>> +
<<mirroring_packages,Mirroring packages>>
[[meaning-of-new]]
=== Meaning of `new`
@@ -3684,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
@@ -4671,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`)
@@ -4751,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.
@@ -5713,3 +5759,25 @@ To support both schemes during evaluation, both would need to be registered expl
----
$ 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.

View File

@@ -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
@@ -84,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
@@ -358,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.
====
@@ -442,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]
@@ -532,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]
====
@@ -628,6 +717,22 @@ 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

View File

@@ -152,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`.
====

View File

@@ -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

View File

@@ -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
@@ -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.
@@ -252,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.

View File

@@ -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:
@@ -134,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
@@ -195,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.
@@ -207,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.
====
@@ -298,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]
@@ -361,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
@@ -391,7 +407,7 @@ For Spring Boot applications, and for users of `pkl-config-java` compiling the g
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)`
The specified annotation type must be annotated with `@java.lang.annotation.Target(ElementType.TYPE_USE)`
or the generated code may not compile.
====
@@ -431,7 +447,7 @@ build.gradle.kts::
+
[source,kotlin]
----
pkl {
pkl {
kotlinCodeGenerators {
register("genKotlin") {
sourceModules.addAll(files("Template1.pkl", "Template2.pkl"))
@@ -451,7 +467,7 @@ $ ./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
@@ -520,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

View File

@@ -44,6 +44,14 @@ 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]
====

View File

@@ -107,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`.
====

View File

@@ -1,6 +1,6 @@
= Pkl 0.28 Release Notes
:version: 0.28
:version-minor: 0.28.0
:version-minor: 0.28.2
:release-date: February 26th, 2025
include::ROOT:partial$component-attributes.adoc[]
@@ -256,6 +256,10 @@ foo { ...bar...baz } // Syntax error
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]).
@@ -337,7 +341,6 @@ For users that use both Pkl and other Truffle languages, this means that their v
* 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]).
* Pkl's version of Kotlin has been upgraded to 2.0 (https://github.com/apple/pkl/pull/900[#900]).
* Allow setting commit id via `-DcommitId` flag when building Pkl (https://github.com/apple/pkl/pull/954[#954]).
== Bugs fixed [small]#🐜#

View 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]

View File

@@ -1,6 +1,68 @@
= 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)

View File

@@ -2,6 +2,7 @@
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]

View File

@@ -41,6 +41,7 @@
* 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]

View File

@@ -21,9 +21,9 @@ import org.pkl.core.repl.ReplResponse
import org.pkl.core.repl.ReplServer
import org.pkl.core.util.IoUtils
import org.pkl.core.http.HttpClient
import org.pkl.core.parser.Parser
import org.pkl.core.parser.ParserError
import org.pkl.core.parser.syntax.ClassProperty
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
@@ -302,7 +302,7 @@ class DocSnippetTestsEngine : HierarchicalTestEngine<DocSnippetTestsEngine.Execu
override fun getType() = Type.TEST
private val parsed: org.pkl.core.parser.syntax.Node by lazy {
private val parsed: org.pkl.parser.syntax.Node by lazy {
when (language) {
"pkl" -> Parser().parseModule(code)
"pkl-expr" -> Parser().parseExpressionInput(code)

View File

@@ -1,7 +1,7 @@
# suppress inspection "UnusedProperty" for whole file
group=org.pkl-lang
version=0.28.0
version=0.29.1
# google-java-format requires jdk.compiler exports
org.gradle.jvmargs= \

View File

@@ -1,5 +1,4 @@
[versions] # ordered alphabetically
antlr = "4.+"
assertj = "3.+"
checksumPlugin = "1.4.0"
clikt = "5.+"
@@ -10,13 +9,13 @@ googleJavaFormat = "1.25.2"
# must not use `+` because used in download URL
# 23.1.x requires JDK 20+
graalVm = "24.1.2"
graalVmJdkVersion = "21.0.5"
graalVmJdkVersion = "21.0.8"
# slightly hacky but convenient place so we remember to update the checksum
graalVmSha256-macos-x64 = "2d9b09e28bc1bb6ff219bf62eacc4626c7740b4f1829ede9ea4450f33e9c0826"
graalVmSha256-macos-aarch64 = "cb68cb2c796f42f37a56fcd1385d8b86cca12e0b46c5618a5ed3ec7dd2260f6f"
graalVmSha256-linux-x64 = "c1960d4f9d278458bde1cd15115ac2f0b3240cb427d51cfeceb79dab91a7f5c9"
graalVmSha256-linux-aarch64 = "3ad68fbb2d13da528dfa0aea9e9345383245ec9c31094dce3905cefba9aac01e"
graalVmSha256-windows-x64 = "d5784cbdc87f84b5cbd6c9d09c6f1d4611954f139fcfc795005c58dffd7f6b41"
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"
@@ -29,6 +28,7 @@ jmh = "1.+"
jmhPlugin = "0.7.2"
jsr305 = "3.+"
junit = "5.+"
junitPlatform = "1.+"
kotlin = "2.0.21"
# 1.7+ generates much more verbose code
kotlinPoet = "1.6.+"
@@ -49,8 +49,6 @@ 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" }
@@ -72,6 +70,7 @@ 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" }

Binary file not shown.

View File

@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=8d97a97984f6cbd2b85fe4c60a743440a347544bf18818048e611f5288d46c94
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
distributionSha256Sum=bd71102213493060956ec229d946beee57158dbd89d0e62b91bca0fa2c5f3531
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

6
gradlew vendored
View File

@@ -114,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.
@@ -205,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.
@@ -213,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.

4
gradlew.bat vendored
View File

@@ -70,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

View File

@@ -2,15 +2,15 @@
"catalogs": {},
"aliases": {
"pkl": {
"script-ref": "org.pkl-lang:pkl-cli-java:0.27.0",
"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.27.0",
"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.27.0",
"script-ref": "org.pkl-lang:pkl-codegen-kotlin:0.29.1",
"java-agents": []
}
},

View File

@@ -2,12 +2,12 @@
# 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.10.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-annotations:2.18.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-core:2.18.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-databind:2.18.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
com.fasterxml.jackson:jackson-bom:2.18.2=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
@@ -31,26 +31,25 @@ com.github.ajalt.mordant:mordant:3.0.1=apiDependenciesMetadata,compileClasspath,
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.36.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
com.google.guava:failureaccess:1.0.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
com.google.guava:guava:33.4.0-jre=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,testRuntimeClasspath
com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
com.networknt:json-schema-validator:1.5.5=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
commons-fileupload:commons-fileupload:1.5=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
commons-io:commons-io:2.11.0=testCompileClasspath,testImplementationDependenciesMetadata,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.1=testRuntimeClasspath
net.minidev:json-smart:2.5.1=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.4.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.apache.httpcomponents.core5:httpcore5-h2:5.3.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.apache.httpcomponents.core5:httpcore5:5.3.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata,testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
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.checkerframework:checker-qual:3.43.0=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
@@ -71,22 +70,16 @@ org.eclipse.jetty:jetty-servlets:11.0.24=testCompileClasspath,testImplementation
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.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.graalvm.compiler:compiler:24.1.2=compileClasspath,compileOnlyDependenciesMetadata
org.graalvm.nativeimage:native-image-base:24.1.2=compileClasspath,compileOnlyDependenciesMetadata
org.graalvm.nativeimage:objectfile:24.1.2=compileClasspath,compileOnlyDependenciesMetadata
org.graalvm.nativeimage:pointsto:24.1.2=compileClasspath,compileOnlyDependenciesMetadata
org.graalvm.nativeimage:svm:24.1.2=compileClasspath,compileOnlyDependenciesMetadata
org.graalvm.nativeimage:truffle-runtime-svm:24.1.2=compileClasspath,compileOnlyDependenciesMetadata
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,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,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,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.graalvm.truffle:truffle-compiler:24.1.2=compileClasspath,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.graalvm.truffle:truffle-runtime: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=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
@@ -100,45 +93,38 @@ org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=kotlinBuildToolsApiClasspat
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,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
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,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath,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,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
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.junit.jupiter:junit-jupiter-api:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-api:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-engine:5.8.2=testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.platform:junit-platform-commons:1.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.platform:junit-platform-commons:1.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.platform:junit-platform-engine:1.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.platform:junit-platform-engine:1.8.2=testJdk17RuntimeClasspath
org.junit.platform:junit-platform-launcher:1.8.2=testJdk17RuntimeClasspath
org.junit:junit-bom:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit:junit-bom:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
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.2.0=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.organicdesign:Paguro:3.10.3=runtimeClasspath,testRuntimeClasspath
org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.snakeyaml:snakeyaml-engine:2.9=runtimeClasspath,testRuntimeClasspath
org.wiremock:wiremock:3.11.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.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
empty=annotationProcessor,archives,compile,intransitiveDependenciesMetadata,javaExecutable,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtime,runtimeOnlyDependenciesMetadata,shadow,signatures,sourcesJar,stagedAlpineLinuxAmd64Executable,stagedLinuxAarch64Executable,stagedLinuxAmd64Executable,stagedMacAarch64Executable,stagedMacAmd64Executable,stagedWindowsAmd64Executable,testAnnotationProcessor,testApiDependenciesMetadata,testCompile,testCompileOnly,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testJdk17AnnotationProcessor,testJdk17ApiDependenciesMetadata,testJdk17CompileOnlyDependenciesMetadata,testJdk17IntransitiveDependenciesMetadata,testJdk17KotlinScriptDefExtensions,testKotlinScriptDef,testKotlinScriptDefExtensions,testRuntime
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

View File

@@ -14,20 +14,22 @@
* 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)
id(libs.plugins.shadow.get().pluginId)
@Suppress("DSL_SCOPE_VIOLATION") alias(libs.plugins.checksum)
alias(libs.plugins.checksum)
}
// make Java executable available to other subprojects
@@ -44,16 +46,7 @@ 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
dependencies {
compileOnly(libs.svm)
compileOnly(libs.truffleSvm)
implementation(libs.truffleRuntime)
compileOnly(libs.graalSdk)
@@ -72,15 +65,6 @@ dependencies {
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 {
@@ -99,15 +83,6 @@ tasks.shadowJar {
exclude("module-info.*")
}
val javaExecutable by
tasks.registering(ExecutableJar::class) {
inJar.set(tasks.shadowJar.flatMap { it.archiveFile })
outJar.set(layout.buildDirectory.file("executable/jpkl"))
// uncomment for debugging
// jvmArgs.addAll("-ea", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005")
}
val testJavaExecutable by
tasks.registering(Test::class) {
testClassesDirs = tasks.test.get().testClassesDirs
@@ -115,7 +90,7 @@ val testJavaExecutable by
// compiled test classes
sourceSets.test.get().output +
// java executable
javaExecutable.get().outputs.files +
tasks.javaExecutable.get().outputs.files +
// test-only dependencies
// (test dependencies that are also main dependencies must already be contained in java
// executable;
@@ -124,12 +99,7 @@ val testJavaExecutable by
}
// Setup `testJavaExecutable` tasks for multi-JDK testing.
val testJavaExecutableOnOtherJdks =
if (buildInfo.multiJdkTesting) {
buildInfo.multiJdkTestingWith(testJavaExecutable)
} else {
emptyList()
}
val testJavaExecutableOnOtherJdks = buildInfo.multiJdkTestingWith(testJavaExecutable)
// Prepare a run of the fat JAR, optionally with a specific Java launcher.
private fun setupJavaExecutableRun(
@@ -139,7 +109,7 @@ private fun setupJavaExecutableRun(
configurator: Exec.() -> Unit = {},
) =
tasks.register(name, Exec::class) {
dependsOn(javaExecutable)
dependsOn(tasks.javaExecutable)
val outputFile = layout.buildDirectory.file(name) // dummy output to satisfy up-to-date check
outputs.file(outputFile)
@@ -148,8 +118,9 @@ private fun setupJavaExecutableRun(
null -> "java"
else -> launcher.get().executablePath.asFile.absolutePath
}
standardOutput = OutputStream.nullOutputStream()
args("-jar", javaExecutable.get().outputs.files.singleFile.toString(), *args)
args("-jar", tasks.javaExecutable.get().outputs.files.singleFile.toString(), *args)
doFirst { outputFile.get().asFile.delete() }
@@ -158,25 +129,6 @@ private fun setupJavaExecutableRun(
configurator()
}
// 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
setupJavaExecutableRun("testStartJavaExecutable", arrayOf("--version"))
// Setup `testStartJavaExecutable` tasks for multi-JDK testing.
val testStartJavaExecutableOnOtherJdks =
if (buildInfo.multiJdkTesting) {
buildInfo.jdkTestRange.map { jdkTarget ->
setupJavaExecutableRun(
"testStartJavaExecutableJdk${jdkTarget.asInt()}",
arrayOf("--version"),
serviceOf<JavaToolchainService>().launcherFor { languageVersion = jdkTarget },
)
}
} else {
emptyList()
}
val evalTestFlags = arrayOf("eval", "-x", "1 + 1", "pkl:base")
fun Exec.useRootDirAndSuppressOutput() {
@@ -205,324 +157,35 @@ val testEvalJavaExecutableOnOtherJdks =
tasks.check {
dependsOn(
testJavaExecutable,
testStartJavaExecutable,
testJavaExecutableOnOtherJdks,
testStartJavaExecutableOnOtherJdks,
testEvalJavaExecutable,
testEvalJavaExecutableOnOtherJdks,
)
}
fun Exec.configureExecutable(
graalVm: BuildInfo.GraalVm,
outputFile: Provider<RegularFile>,
extraArgs: List<String> = listOf(),
) {
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.graalSdk).map { it.get().module.name }
// https://www.graalvm.org/22.0/reference-manual/native-image/Options/
argumentProviders.add(
CommandLineArgumentProvider {
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:IncludeResources=org/pkl/commons/cli/PklCARoots.pem")
add("-H:Class=org.pkl.cli.Main")
add("-o")
add(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")
}
if (buildInfo.isNativeArch) {
add("-march=native")
} else {
add("-march=compatibility")
}
// 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}")
// Pass through all `HOMEBREW_` prefixed environment variables to allow build with shimmed
// tools.
addAll(environment.keys.filter { it.startsWith("HOMEBREW_") }.map { "-E$it" })
addAll(extraArgs)
}
}
)
tasks.checkNative {
dependsOn(":pkl-core:checkNative")
dependsOn(":pkl-server:checkNative")
}
/** 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"),
)
}
/** 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"),
)
}
/** 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"),
listOf(
// Ensure compatibility for kernels with page size set to 4k, 16k and 64k
// (e.g. Raspberry Pi 5, Asahi Linux)
"-H:PageSize=65536"
),
)
}
/**
* 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"),
)
}
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)
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, or with `java -jar <path/to/jpkl>`.
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

View File

@@ -16,19 +16,23 @@
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.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
@@ -47,8 +51,8 @@ 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`
@@ -83,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.
*/
@@ -138,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
@@ -150,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)
}
@@ -167,34 +197,49 @@ constructor(
StandardOpenOption.WRITE,
StandardOpenOption.APPEND,
)
outputFile.writeString(
output,
Charsets.UTF_8,
StandardOpenOption.WRITE,
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 != '/' }
@@ -216,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)
@@ -240,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()
}
}
}

View File

@@ -74,9 +74,9 @@ 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 {

View File

@@ -65,6 +65,12 @@ constructor(
val moduleNames = mutableSetOf<String>()
val reporter = SimpleReport(useColor)
val allTestResults = mutableListOf<TestResults>()
val junitDir = testOptions.junitDir
if (junitDir != null) {
junitDir.toFile().mkdirs()
}
for ((idx, moduleUri) in sources.withIndex()) {
try {
val results = evaluator.evaluateTest(uri(moduleUri), testOptions.overwrite)
@@ -78,9 +84,7 @@ constructor(
consoleWriter.append('\n')
}
consoleWriter.flush()
val junitDir = testOptions.junitDir
if (junitDir != null) {
junitDir.toFile().mkdirs()
val moduleName = "${results.moduleName}.xml"
if (moduleName in moduleNames) {
throw RuntimeException(
@@ -94,7 +98,10 @@ constructor(
)
}
moduleNames += moduleName
JUnitReport().reportToPath(results, junitDir.resolve(moduleName))
if (!testOptions.junitAggregateReports) {
JUnitReport().reportToPath(results, junitDir.resolve(moduleName))
}
}
} catch (ex: Exception) {
errWriter.appendLine("Error evaluating module ${moduleUri.path}:")
@@ -106,6 +113,11 @@ constructor(
failed = true
}
}
if (testOptions.junitAggregateReports && junitDir != null) {
val fileName = "${testOptions.junitAggregateSuiteName}.xml"
JUnitReport(testOptions.junitAggregateSuiteName)
.summarizeToPath(allTestResults, junitDir.resolve(fileName))
}
consoleWriter.append('\n')
reporter.summarize(allTestResults, consoleWriter)
consoleWriter.flush()

View File

@@ -15,6 +15,7 @@
*/
package org.pkl.cli.commands
import com.github.ajalt.clikt.completion.CompletionCandidates
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.option
@@ -33,6 +34,7 @@ class EvalCommand : ModulesCommand(name = "eval", helpLink = helpLink) {
names = arrayOf("-o", "--output-path"),
metavar = "path",
help = "File path where the output file is placed.",
completionCandidates = CompletionCandidates.Path,
)
.single()
@@ -59,6 +61,7 @@ class EvalCommand : ModulesCommand(name = "eval", helpLink = helpLink) {
names = arrayOf("-m", "--multiple-file-output-path"),
metavar = "path",
help = "Directory where a module's multiple file output is placed.",
completionCandidates = CompletionCandidates.Path,
)
.single()
.validate {

View File

@@ -15,6 +15,7 @@
*/
package org.pkl.cli.commands
import com.github.ajalt.clikt.completion.CompletionCandidates
import com.github.ajalt.clikt.core.Context
import com.github.ajalt.clikt.core.NoOpCliktCommand
import com.github.ajalt.clikt.core.subcommands
@@ -116,6 +117,7 @@ class PackageCommand : BaseCommand(name = "package", helpLink = helpLink) {
names = arrayOf("--output-path"),
help = "The directory to write artifacts to",
metavar = "path",
completionCandidates = CompletionCandidates.Path,
)
.single()
.default(".out/%{name}@%{version}")

View File

@@ -15,6 +15,7 @@
*/
package org.pkl.cli.commands
import com.github.ajalt.clikt.completion.CompletionCommand
import com.github.ajalt.clikt.core.Context
import com.github.ajalt.clikt.core.NoOpCliktCommand
import com.github.ajalt.clikt.core.context
@@ -48,6 +49,11 @@ class RootCommand : NoOpCliktCommand(name = "pkl") {
ProjectCommand(),
DownloadPackageCommand(),
AnalyzeCommand(),
CompletionCommand(
name = "shell-completion",
help = "Generate a completion script for the given shell",
epilog = "For more information, visit $helpLink",
),
)
}
}

View File

@@ -15,6 +15,7 @@
*/
package org.pkl.cli.commands
import com.github.ajalt.clikt.completion.CompletionCandidates
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.convert
import com.github.ajalt.clikt.parameters.arguments.multiple
@@ -30,7 +31,11 @@ class TestCommand : BaseCommand(name = "test", helpLink = helpLink) {
override val helpString = "Run tests within the given module(s)"
val modules: List<URI> by
argument(name = "modules", help = "Module paths or URIs to evaluate.")
argument(
name = "modules",
help = "Module paths or URIs to evaluate.",
completionCandidates = CompletionCandidates.Path,
)
.convert { BaseOptions.parseModuleName(it) }
.multiple()

View File

@@ -18,10 +18,11 @@ package org.pkl.cli
import com.github.tomakehurst.wiremock.client.WireMock.*
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo
import com.github.tomakehurst.wiremock.junit5.WireMockTest
import java.io.StringReader
import java.io.StringWriter
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.net.ServerSocket
import java.net.URI
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Path
import java.time.Duration
@@ -29,22 +30,20 @@ import java.util.regex.Pattern
import kotlin.io.path.*
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatCode
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.*
import org.junit.jupiter.api.condition.DisabledOnOs
import org.junit.jupiter.api.condition.EnabledOnOs
import org.junit.jupiter.api.condition.OS
import org.junit.jupiter.api.io.TempDir
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.EnumSource
import org.pkl.commons.*
import org.pkl.commons.cli.CliBaseOptions
import org.pkl.commons.cli.CliException
import org.pkl.commons.readString
import org.pkl.commons.test.FileTestUtils
import org.pkl.commons.test.PackageServer
import org.pkl.commons.toPath
import org.pkl.commons.writeString
import org.pkl.core.OutputFormat
import org.pkl.core.SecurityManagers
import org.pkl.core.util.IoUtils
@@ -157,7 +156,6 @@ person:
)
assertThat(outputFiles).hasSize(1)
@Suppress("HttpUrlsUsage")
checkOutputFile(
outputFiles[0],
"test.plist",
@@ -469,8 +467,8 @@ result = someLib.x
@Test
fun `take input from stdin`() {
val stdin = StringReader(defaultContents)
val stdout = StringWriter()
val stdin = ByteArrayInputStream(defaultContents.toByteArray(StandardCharsets.UTF_8))
val stdout = ByteArrayOutputStream()
val evaluator =
CliEvaluator(
CliEvaluatorOptions(
@@ -481,7 +479,8 @@ result = someLib.x
stdout,
)
evaluator.run()
assertThat(stdout.toString().trim()).isEqualTo(defaultContents.replace("20 + 10", "30").trim())
assertThat(stdout.toString(StandardCharsets.UTF_8).trim())
.isEqualTo(defaultContents.replace("20 + 10", "30").trim())
}
@Test
@@ -725,6 +724,39 @@ result = someLib.x
assertThat(output).endsWith("\n")
}
@Test
fun `file output throws if output file is a directory`() {
val sourceFiles =
listOf(
writePklFile(
"test.pkl",
"""
name = "test"
output {
files {
["\(name).txt"] {
text = "test"
}
}
}
"""
.trimIndent(),
)
)
val err =
assertThrows<CliException> {
evalToFiles(
CliEvaluatorOptions(
CliBaseOptions(sourceModules = sourceFiles),
outputPath = tempDir.toString(),
)
)
}
assertThat(err)
.hasMessageContaining("Output file `$tempDir` is a directory. ")
.hasMessageContaining("Did you mean `--multiple-file-output-path`?")
}
@Test
fun `multiple file output writes multiple files to the provided directory`() {
val contents =
@@ -1068,9 +1100,9 @@ result = someLib.x
CliBaseOptions(sourceModules = listOf(moduleUri), workingDir = tempDir),
expression = "foo",
)
val buffer = StringWriter()
CliEvaluator(options, consoleWriter = buffer).run()
assertThat(buffer.toString())
val buffer = ByteArrayOutputStream()
CliEvaluator(options, outputStream = buffer).run()
assertThat(buffer.toString(StandardCharsets.UTF_8))
.isEqualTo(
"""
new Dynamic { bar = 1 }
@@ -1099,9 +1131,9 @@ result = someLib.x
CliBaseOptions(sourceModules = listOf(moduleUri), workingDir = tempDir),
expression = "person",
)
val buffer = StringWriter()
CliEvaluator(options, consoleWriter = buffer).run()
assertThat(buffer.toString()).isEqualTo("Person(Frodo)")
val buffer = ByteArrayOutputStream()
CliEvaluator(options, outputStream = buffer).run()
assertThat(buffer.toString(StandardCharsets.UTF_8)).isEqualTo("Person(Frodo)")
}
@Test
@@ -1121,9 +1153,10 @@ result = someLib.x
CliBaseOptions(sourceModules = listOf(moduleUri), workingDir = tempDir),
expression = "person",
)
val buffer = StringWriter()
CliEvaluator(options, consoleWriter = buffer).run()
assertThat(buffer.toString()).isEqualTo("new Dynamic { friend { name = \"Bilbo\" } }")
val buffer = ByteArrayOutputStream()
CliEvaluator(options, outputStream = buffer).run()
assertThat(buffer.toString(StandardCharsets.UTF_8))
.isEqualTo("new Dynamic { friend { name = \"Bilbo\" } }")
}
@Test
@@ -1149,9 +1182,9 @@ result = someLib.x
CliEvaluatorOptions(
CliBaseOptions(sourceModules = listOf(moduleUri), workingDir = tempDir, noProject = true)
)
val buffer = StringWriter()
CliEvaluator(options, consoleWriter = buffer).run()
assertThat(buffer.toString()).isEqualTo("res = 1\n")
val buffer = ByteArrayOutputStream()
CliEvaluator(options, outputStream = buffer).run()
assertThat(buffer.toString(StandardCharsets.UTF_8)).isEqualTo("res = 1\n")
}
@Test
@@ -1182,9 +1215,9 @@ result = someLib.x
)
val options =
CliEvaluatorOptions(CliBaseOptions(sourceModules = listOf(moduleUri), workingDir = tempDir))
val buffer = StringWriter()
CliEvaluator(options, consoleWriter = buffer).run()
assertThat(buffer.toString())
val buffer = ByteArrayOutputStream()
CliEvaluator(options, outputStream = buffer).run()
assertThat(buffer.toString(StandardCharsets.UTF_8))
.isEqualTo(
"""
res {
@@ -1197,6 +1230,92 @@ result = someLib.x
)
}
@Test
fun `noProxy settings from PklProject file`() {
val moduleUri =
writePklFile(
"test.pkl",
"""
res = read("https://localhost:${packageServer.port}/birds@0.5.0").bytes.sha256
"""
.trimIndent(),
)
writePklFile(
"PklProject",
// language=Pkl
"""
amends "pkl:Project"
evaluatorSettings {
http {
proxy {
address = "http://example.example"
noProxy {
"localhost:${packageServer.port}"
}
}
}
}
"""
.trimIndent(),
)
val options =
CliEvaluatorOptions(
CliBaseOptions(
sourceModules = listOf(moduleUri),
workingDir = tempDir,
caCertificates = listOf(FileTestUtils.selfSignedCertificate),
)
)
val buffer = ByteArrayOutputStream()
CliEvaluator(options, outputStream = buffer).run()
assertThat(buffer.toString(StandardCharsets.UTF_8))
.isEqualTo("res = \"b27206b80f4f227752b6f02143887f3ea41e554542cec38f7b572b987566c4de\"\n")
}
@Test
fun `noProxy settings from settings file`() {
val moduleUri =
writePklFile(
"test.pkl",
"""
res = read("https://localhost:${packageServer.port}/birds@0.5.0").bytes.sha256
"""
.trimIndent(),
)
val settingsFile =
writePklFile(
"settings.pkl",
// language=Pkl
"""
amends "pkl:settings"
http {
proxy {
address = "http://example.example"
noProxy {
"localhost:${packageServer.port}"
}
}
}
"""
.trimIndent(),
)
val options =
CliEvaluatorOptions(
CliBaseOptions(
sourceModules = listOf(moduleUri),
workingDir = tempDir,
caCertificates = listOf(FileTestUtils.selfSignedCertificate),
settings = settingsFile,
)
)
val buffer = ByteArrayOutputStream()
CliEvaluator(options, outputStream = buffer).run()
assertThat(buffer.toString(StandardCharsets.UTF_8))
.isEqualTo("res = \"b27206b80f4f227752b6f02143887f3ea41e554542cec38f7b572b987566c4de\"\n")
}
@Test
fun `setting noCache will skip writing to the cache dir`() {
val moduleUri =
@@ -1209,7 +1328,7 @@ result = someLib.x
"""
.trimIndent(),
)
val buffer = StringWriter()
val buffer = ByteArrayOutputStream()
val options =
CliEvaluatorOptions(
CliBaseOptions(
@@ -1221,8 +1340,8 @@ result = someLib.x
testPort = packageServer.port,
)
)
CliEvaluator(options, consoleWriter = buffer).run()
assertThat(buffer.toString())
CliEvaluator(options, outputStream = buffer).run()
assertThat(buffer.toString(StandardCharsets.UTF_8))
.isEqualTo(
"""
res {
@@ -1557,10 +1676,10 @@ result = someLib.x
}
private fun evalToConsole(options: CliEvaluatorOptions): String {
val reader = StringReader("")
val writer = StringWriter()
val reader = ByteArrayInputStream(byteArrayOf())
val writer = ByteArrayOutputStream()
CliEvaluator(options, reader, writer).run()
return writer.toString()
return writer.toString(StandardCharsets.UTF_8)
}
private fun checkOutputFile(file: Path, name: String, contents: String) {

View File

@@ -119,6 +119,44 @@ class CliMainTest {
assertThat(ex.message).contains("URI `file:my file.txt` has invalid syntax")
}
@Test
fun `invalid rewrites -- non-HTTP URI`() {
val ex =
assertThrows<BadParameterValue> {
rootCmd.parse(arrayOf("eval", "--http-rewrite", "foo=bar", "mymodule.pkl"))
}
assertThat(ex.message)
.contains("Rewrite rule must start with 'http://' or 'https://', but was 'foo'")
}
@Test
fun `invalid rewrites -- invalid URI`() {
val ex =
assertThrows<BadParameterValue> {
rootCmd.parse(arrayOf("eval", "--http-rewrite", "https://foo bar=baz", "mymodule.pkl"))
}
assertThat(ex.message).contains("Rewrite target `https://foo bar` has invalid syntax")
}
@Test
fun `invalid rewrites -- doesn't end with slash`() {
val ex =
assertThrows<BadParameterValue> {
rootCmd.parse(
arrayOf("eval", "--http-rewrite", "http://foo.com=https://bar.com", "mymodule.pkl")
)
}
assertThat(ex.message).contains("Rewrite rule must end with '/', but was 'http://foo.com'")
}
@Test
fun `missing --http-no-proxy flag is null`(@TempDir tempDir: Path) {
val inputFile = tempDir.resolve("test.pkl").writeString("").toString()
val command = EvalCommand()
command.parse(arrayOf(inputFile))
assertThat(command.baseOptions.noProxy).isNull()
}
private fun makeInput(tempDir: Path, fileName: String = "test.pkl"): String {
val code = "x = 1"
return tempDir.resolve(fileName).writeString(code).toString()

View File

@@ -0,0 +1,34 @@
/*
* 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 com.github.ajalt.clikt.testing.test
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.pkl.cli.commands.RootCommand
class CliShellCompletionTest {
@Test
fun `shell completion command supports required shells`() {
val shellList = listOf("bash", "zsh", "fish")
for (shell in shellList) {
val result = RootCommand().test("shell-completion $shell")
assertThat(result.stdout).contains("Command completion for pkl")
}
}
}

View File

@@ -385,6 +385,174 @@ class CliTestRunnerTest {
assertThatCode { runner.run() }.hasMessageContaining("failed")
}
@Test
fun `CliTestRunner test per module`(@TempDir tempDir: Path) {
val code1 =
"""
amends "pkl:test"
facts {
["foo"] {
true
}
}
"""
.trimIndent()
val code2 =
"""
amends "pkl:test"
facts {
["bar"] {
true
}
}
"""
.trimIndent()
val input1 = tempDir.resolve("test1.pkl").writeString(code1).toString()
val input2 = tempDir.resolve("test2.pkl").writeString(code2).toString()
val noopWriter = noopWriter()
val opts =
CliBaseOptions(
sourceModules = listOf(input1.toUri(), input2.toUri()),
settings = URI("pkl:settings"),
)
val testOpts = CliTestOptions(junitDir = tempDir)
val runner = CliTestRunner(opts, testOpts, noopWriter, noopWriter)
runner.run()
assertThat(tempDir.resolve("test1.xml")).isNotEmptyFile()
assertThat(tempDir.resolve("test2.xml")).isNotEmptyFile()
}
@Test
fun `CliTestRunner test aggregate`(@TempDir tempDir: Path) {
val code1 =
"""
amends "pkl:test"
facts {
["foo"] {
true
}
["bar"] {
5 == 9
}
}
"""
.trimIndent()
val code2 =
"""
amends "pkl:test"
facts {
["xxx"] {
false
}
["yyy"] {
false
}
["zzz"] {
true
}
}
"""
.trimIndent()
val input1 = tempDir.resolve("test1.pkl").writeString(code1).toString()
val input2 = tempDir.resolve("test2.pkl").writeString(code2).toString()
val noopWriter = noopWriter()
val opts =
CliBaseOptions(
sourceModules = listOf(input1.toUri(), input2.toUri()),
settings = URI("pkl:settings"),
)
val testOpts = CliTestOptions(junitDir = tempDir, junitAggregateReports = true)
val runner = CliTestRunner(opts, testOpts, noopWriter, noopWriter)
assertThatCode { runner.run() }.hasMessageContaining("failed")
assertThat(tempDir.resolve("pkl-tests.xml")).isNotEmptyFile()
assertThat(tempDir.resolve("test1.xml")).doesNotExist()
assertThat(tempDir.resolve("test2.xml")).doesNotExist()
val junitReport = tempDir.resolve("pkl-tests.xml").readString().stripFileAndLines(tempDir)
assertThat(junitReport)
.isEqualTo(
"""
<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="pkl-tests" tests="5" failures="3">
<testsuite name="test1" tests="2" failures="1">
<testcase classname="test1.facts" name="foo"></testcase>
<testcase classname="test1.facts" name="bar">
<failure message="Fact Failure">5 == 9 (/tempDir/test1.pkl, line xx)</failure>
</testcase>
</testsuite>
<testsuite name="test2" tests="3" failures="2">
<testcase classname="test2.facts" name="xxx">
<failure message="Fact Failure">false (/tempDir/test2.pkl, line xx)</failure>
</testcase>
<testcase classname="test2.facts" name="yyy">
<failure message="Fact Failure">false (/tempDir/test2.pkl, line xx)</failure>
</testcase>
<testcase classname="test2.facts" name="zzz"></testcase>
</testsuite>
</testsuites>
"""
.trimIndent()
)
}
@Test
fun `CliTestRunner test aggregate suite name`(@TempDir tempDir: Path) {
val code1 =
"""
amends "pkl:test"
facts {
["foo"] {
true
}
}
"""
.trimIndent()
val code2 =
"""
amends "pkl:test"
facts {
["bar"] {
true
}
}
"""
.trimIndent()
val input1 = tempDir.resolve("test1.pkl").writeString(code1).toString()
val input2 = tempDir.resolve("test2.pkl").writeString(code2).toString()
val noopWriter = noopWriter()
val opts =
CliBaseOptions(
sourceModules = listOf(input1.toUri(), input2.toUri()),
settings = URI("pkl:settings"),
)
val testOpts =
CliTestOptions(
junitDir = tempDir,
junitAggregateReports = true,
junitAggregateSuiteName = "custom",
)
val runner = CliTestRunner(opts, testOpts, noopWriter, noopWriter)
runner.run()
assertThat(tempDir.resolve("custom.xml")).isNotEmptyFile()
assertThat(tempDir.resolve("pkl-tests.xml")).doesNotExist()
assertThat(tempDir.resolve("test1.xml")).doesNotExist()
assertThat(tempDir.resolve("test2.xml")).doesNotExist()
}
@Test
fun `no source modules specified has same message as pkl eval`() {
val e1 = assertThrows<CliException> { CliTestRunner(CliBaseOptions(), CliTestOptions()).run() }

View File

@@ -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.
@@ -64,4 +64,11 @@ class ReplMessagesTest {
startIndex = examples.indexOf("```", endIndex + 3)
}
}
@Test
fun `handle single backtick`() {
val responses = server.handleRequest(ReplRequest.Eval("1", "`", true, true))
assertThat(responses.size).isEqualTo(1)
assertThat(responses).hasOnlyElementsOfType(ReplResponse.EvalError::class.java)
}
}

View File

@@ -21,11 +21,11 @@ com.github.ajalt.mordant:mordant-jvm:3.0.1=compileClasspath,runtimeClasspath,tes
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.palantir.javapoet:javapoet:0.6.0=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
com.palantir.javapoet:javapoet:0.7.0=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
io.leangen.geantyref:geantyref:1.3.16=testRuntimeClasspath
net.bytebuddy:byte-buddy:1.15.11=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
net.java.dev.jna:jna:5.14.0=runtimeClasspath,testRuntimeClasspath
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata,testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
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=runtimeClasspath,testRuntimeClasspath
org.graalvm.sdk:collections:24.1.2=runtimeClasspath,testRuntimeClasspath
@@ -44,35 +44,27 @@ org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=kotlinBuildToolsApiClasspat
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,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
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,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath,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,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
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.junit.jupiter:junit-jupiter-api:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-api:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-engine:5.8.2=testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.platform:junit-platform-commons:1.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.platform:junit-platform-commons:1.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.platform:junit-platform-engine:1.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.platform:junit-platform-engine:1.8.2=testJdk17RuntimeClasspath
org.junit.platform:junit-platform-launcher:1.8.2=testJdk17RuntimeClasspath
org.junit:junit-bom:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit:junit-bom:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
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.2.0=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.organicdesign:Paguro:3.10.3=runtimeClasspath,testRuntimeClasspath
org.snakeyaml:snakeyaml-engine:2.9=runtimeClasspath,testRuntimeClasspath
empty=annotationProcessor,compileOnlyDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtimeOnlyDependenciesMetadata,signatures,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testJdk17AnnotationProcessor,testJdk17ApiDependenciesMetadata,testJdk17CompileOnlyDependenciesMetadata,testJdk17IntransitiveDependenciesMetadata,testJdk17KotlinScriptDefExtensions,testKotlinScriptDef,testKotlinScriptDefExtensions
org.snakeyaml:snakeyaml-engine:2.10=runtimeClasspath,testRuntimeClasspath
empty=annotationProcessor,compileOnlyDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,shadow,signatures,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions

View File

@@ -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.
@@ -17,6 +17,7 @@ plugins {
pklAllProjects
pklKotlinLibrary
pklPublishLibrary
pklJavaExecutable
}
dependencies {
@@ -31,6 +32,14 @@ dependencies {
testImplementation(projects.pklCommonsTest)
}
executable {
javaName = "pkl-codegen-java"
documentationName = "Pkl Codegen Java"
javaPublicationName = "pkl-cli-codegen-java"
mainClass = "org.pkl.codegen.java.Main"
website = "https://pkl-lang.org/main/current/java-binding/codegen.html"
}
// with `org.gradle.parallel=true` and without the line below, `test` strangely runs into:
// java.lang.NoClassDefFoundError: Lorg/pkl/config/java/ConfigEvaluator;
// perhaps somehow related to InMemoryJavaCompiler?

View File

@@ -29,6 +29,9 @@ data class CliJavaCodeGeneratorOptions(
/** The characters to use for indenting generated source code. */
val indent: String = " ",
/** Whether to add a `@Generated` annotation to the types to be generated. */
val addGeneratedAnnotation: Boolean = false,
/**
* Whether to generate public getter methods and private/protected fields instead of public
* fields.
@@ -82,6 +85,7 @@ data class CliJavaCodeGeneratorOptions(
internal fun toJavaCodeGeneratorOptions() =
JavaCodeGeneratorOptions(
indent,
addGeneratedAnnotation,
generateGetters,
generateJavadoc,
generateSpringBootConfig,

View File

@@ -47,6 +47,9 @@ data class JavaCodeGeneratorOptions(
/** The characters to use for indenting generated Java code. */
val indent: String = " ",
/** Adds the `org.pkl.config.java.Generated` annotation to the classes to be generated. */
val addGeneratedAnnotation: Boolean = false,
/**
* Whether to generate public getter methods and protected final fields instead of public final
* fields.
@@ -342,13 +345,22 @@ class JavaCodeGenerator(
var builderSize = 50
val appendBuilder = CodeBlock.builder()
for (propertyName in allProperties.keys) {
for ((propertyName, property) in allProperties) {
builderSize += 50
appendBuilder.addStatement(
"appendProperty(builder, \$S, this.\$N)",
propertyName,
propertyName,
)
if (property.type.isBytesClass) {
appendBuilder.addStatement(
"appendProperty(builder, \$S, \$T.toString(this.\$N))",
propertyName,
Arrays::class.java,
propertyName,
)
} else {
appendBuilder.addStatement(
"appendProperty(builder, \$S, this.\$N)",
propertyName,
propertyName,
)
}
}
builder
@@ -551,6 +563,11 @@ class JavaCodeGenerator(
fun generateClass(): TypeSpec.Builder {
val builder =
TypeSpec.classBuilder(javaPoetClassName.simpleName()).addModifiers(Modifier.PUBLIC)
if (codegenOptions.addGeneratedAnnotation) {
val name = ClassName.get("org.pkl.config.java", "Generated")
val generated = AnnotationSpec.builder(name).build()
builder.addAnnotation(generated)
}
// stateless final module classes are non-instantiable by choice
val isInstantiable =
@@ -725,6 +742,9 @@ class JavaCodeGenerator(
}
}
private val PType.isBytesClass: Boolean
get() = this is PType.Class && this.pClass.info == PClassInfo.Bytes
private fun PType.toJavaPoetName(nullable: Boolean = false, boxed: Boolean = false): TypeName =
when (this) {
PType.UNKNOWN -> OBJECT.nullableIf(nullable)
@@ -744,6 +764,7 @@ class JavaCodeGenerator(
PClassInfo.Float -> TypeName.DOUBLE.boxIf(boxed).nullableIf(nullable)
PClassInfo.Duration -> DURATION.nullableIf(nullable)
PClassInfo.DataSize -> DATA_SIZE.nullableIf(nullable)
PClassInfo.Bytes -> ArrayTypeName.of(TypeName.BYTE)
PClassInfo.Pair ->
ParameterizedTypeName.get(
PAIR,

View File

@@ -55,6 +55,13 @@ class PklJavaCodegenCommand : ModulesCommand(name = "pkl-codegen-java", helpLink
)
.default(defaults.indent)
private val addGeneratedAnnotation: Boolean by
option(
names = arrayOf("--add-generated-annotation"),
help = "Whether to add a @Generated annotation to the types to be generated.",
)
.flag()
private val generateGetters: Boolean by
option(
names = arrayOf("--generate-getters"),
@@ -132,6 +139,7 @@ class PklJavaCodegenCommand : ModulesCommand(name = "pkl-codegen-java", helpLink
base = baseOptions.baseOptions(modules, projectOptions),
outputDir = outputDir,
indent = indent,
addGeneratedAnnotation = addGeneratedAnnotation,
generateGetters = generateGetters,
generateJavadoc = generateJavadoc,
generateSpringBootConfig = generateSpringBoot,

View File

@@ -87,6 +87,7 @@ class JavaCodeGeneratorTest {
any: Any
nonNull: NonNull
enum: Direction
bytes: Bytes
}
class Other {
@@ -202,6 +203,7 @@ class JavaCodeGeneratorTest {
name = pigeon
}
_enum = north
bytes = [1, 2, 3, 4]
}
"""
.trimIndent()
@@ -542,6 +544,7 @@ class JavaCodeGeneratorTest {
assertThat(readProperty(propertyTypes, "regex")).isInstanceOf(Pattern::class.java)
assertThat(readProperty(propertyTypes, "any")).isEqualTo(other)
assertThat(readProperty(propertyTypes, "nonNull")).isEqualTo(other)
assertThat(readProperty(propertyTypes, "bytes")).isEqualTo(byteArrayOf(1, 2, 3, 4))
}
private fun readProperty(obj: Any, property: String): Any? =
@@ -856,6 +859,24 @@ class JavaCodeGeneratorTest {
assertThat(fooClass.declaredFields).allSatisfy(Consumer { it.name.startsWith("_") })
}
@Test
fun generatedAnnotation() {
val javaCode =
generateJavaCode(
"""
module my.mod
class GeneratedAnnotation {
test: Boolean = true
}
"""
.trimIndent(),
JavaCodeGeneratorOptions(addGeneratedAnnotation = true),
)
assertThat(javaCode).compilesSuccessfully().isEqualToResourceFile("GeneratedAnnotation.jva")
}
@Test
fun getters() {
val javaCode =
@@ -2313,6 +2334,7 @@ class JavaCodeGeneratorTest {
other,
other,
enumValue,
byteArrayOf(1, 2, 3, 4),
)
return other to propertyTypes

View File

@@ -0,0 +1,63 @@
package my;
import java.lang.Object;
import java.lang.Override;
import java.lang.String;
import java.lang.StringBuilder;
import java.util.Objects;
import org.pkl.config.java.Generated;
import org.pkl.config.java.mapper.Named;
@Generated
public final class Mod {
private Mod() {
}
private static void appendProperty(StringBuilder builder, String name, Object value) {
builder.append("\n ").append(name).append(" = ");
String[] lines = Objects.toString(value).split("\n");
builder.append(lines[0]);
for (int i = 1; i < lines.length; i++) {
builder.append("\n ").append(lines[i]);
}
}
@Generated
public static final class GeneratedAnnotation {
public final boolean test;
public GeneratedAnnotation(@Named("test") boolean test) {
this.test = test;
}
public GeneratedAnnotation withTest(boolean test) {
return new GeneratedAnnotation(test);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (this.getClass() != obj.getClass()) return false;
GeneratedAnnotation other = (GeneratedAnnotation) obj;
if (!Objects.equals(this.test, other.test)) return false;
return true;
}
@Override
public int hashCode() {
int result = 1;
result = 31 * result + Objects.hashCode(this.test);
return result;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder(100);
builder.append(GeneratedAnnotation.class.getSimpleName()).append(" {");
appendProperty(builder, "test", this.test);
builder.append("\n}");
return builder.toString();
}
}
}

View File

@@ -4,6 +4,7 @@ import java.lang.Object;
import java.lang.Override;
import java.lang.String;
import java.lang.StringBuilder;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -86,6 +87,8 @@ public final class Mod {
public final @NonNull Direction _enum;
public final byte[] bytes;
public PropertyTypes(@Named("boolean") boolean _boolean, @Named("int") long _int,
@Named("float") double _float, @Named("string") @NonNull String string,
@Named("duration") @NonNull Duration duration,
@@ -106,7 +109,7 @@ public final class Mod {
@Named("container2") @NonNull Map<@NonNull String, @NonNull Other> container2,
@Named("other") @NonNull Other other, @Named("regex") @NonNull Pattern regex,
@Named("any") Object any, @Named("nonNull") @NonNull Object nonNull,
@Named("enum") @NonNull Direction _enum) {
@Named("enum") @NonNull Direction _enum, @Named("bytes") byte[] bytes) {
this._boolean = _boolean;
this._int = _int;
this._float = _float;
@@ -134,114 +137,119 @@ public final class Mod {
this.any = any;
this.nonNull = nonNull;
this._enum = _enum;
this.bytes = bytes;
}
public PropertyTypes withBoolean(boolean _boolean) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withInt(long _int) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withFloat(double _float) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withString(@NonNull String string) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withDuration(@NonNull Duration duration) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withDurationUnit(@NonNull DurationUnit durationUnit) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withDataSize(@NonNull DataSize dataSize) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withDataSizeUnit(@NonNull DataSizeUnit dataSizeUnit) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withNullable(String nullable) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withNullable2(String nullable2) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withPair(@NonNull Pair<Object, Object> pair) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withPair2(@NonNull Pair<@NonNull String, @NonNull Other> pair2) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withColl(@NonNull Collection<Object> coll) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withColl2(@NonNull Collection<@NonNull Other> coll2) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withList(@NonNull List<Object> list) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withList2(@NonNull List<@NonNull Other> list2) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withSet(@NonNull Set<Object> set) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withSet2(@NonNull Set<@NonNull Other> set2) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withMap(@NonNull Map<Object, Object> map) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withMap2(@NonNull Map<@NonNull String, @NonNull Other> map2) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withContainer(@NonNull Map<Object, Object> container) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withContainer2(@NonNull Map<@NonNull String, @NonNull Other> container2) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withOther(@NonNull Other other) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withRegex(@NonNull Pattern regex) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withAny(Object any) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withNonNull(@NonNull Object nonNull) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withEnum(@NonNull Direction _enum) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum);
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
public PropertyTypes withBytes(byte[] bytes) {
return new PropertyTypes(_boolean, _int, _float, string, duration, durationUnit, dataSize, dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map, map2, container, container2, other, regex, any, nonNull, _enum, bytes);
}
@Override
@@ -277,6 +285,7 @@ public final class Mod {
if (!Objects.equals(this.any, other.any)) return false;
if (!Objects.equals(this.nonNull, other.nonNull)) return false;
if (!Objects.equals(this._enum, other._enum)) return false;
if (!Objects.equals(this.bytes, other.bytes)) return false;
return true;
}
@@ -310,12 +319,13 @@ public final class Mod {
result = 31 * result + Objects.hashCode(this.any);
result = 31 * result + Objects.hashCode(this.nonNull);
result = 31 * result + Objects.hashCode(this._enum);
result = 31 * result + Objects.hashCode(this.bytes);
return result;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder(1400);
StringBuilder builder = new StringBuilder(1450);
builder.append(PropertyTypes.class.getSimpleName()).append(" {");
appendProperty(builder, "_boolean", this._boolean);
appendProperty(builder, "_int", this._int);
@@ -344,6 +354,7 @@ public final class Mod {
appendProperty(builder, "any", this.any);
appendProperty(builder, "nonNull", this.nonNull);
appendProperty(builder, "_enum", this._enum);
appendProperty(builder, "bytes", Arrays.toString(this.bytes));
builder.append("\n}");
return builder.toString();
}

View File

@@ -25,7 +25,7 @@ com.squareup:kotlinpoet:1.6.0=compileClasspath,implementationDependenciesMetadat
io.leangen.geantyref:geantyref:1.3.16=testRuntimeClasspath
net.bytebuddy:byte-buddy:1.15.11=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
net.java.dev.jna:jna:5.14.0=runtimeClasspath,testRuntimeClasspath
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata,testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
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=runtimeClasspath,testRuntimeClasspath
org.graalvm.sdk:collections:24.1.2=runtimeClasspath,testRuntimeClasspath
@@ -33,57 +33,40 @@ org.graalvm.sdk:graal-sdk:24.1.2=runtimeClasspath,testRuntimeClasspath
org.graalvm.sdk:nativeimage:24.1.2=runtimeClasspath,testRuntimeClasspath
org.graalvm.sdk:word:24.1.2=runtimeClasspath,testRuntimeClasspath
org.graalvm.truffle:truffle-api:24.1.2=runtimeClasspath,testRuntimeClasspath
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,testRuntimeClasspath
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,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-compiler-runner:2.0.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=testRuntimeOnlyDependenciesMetadata
org.jetbrains.kotlin:kotlin-daemon-client:2.0.21=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,testRuntimeClasspath
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=compileClasspath,implementationDependenciesMetadata,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-script-runtime:1.7.10=testRuntimeOnlyDependenciesMetadata
org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-script-util:1.7.10=testRuntimeOnlyDependenciesMetadata
org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=testRuntimeOnlyDependenciesMetadata
org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=testRuntimeOnlyDependenciesMetadata
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-scripting-jsr223:2.0.21=testRuntimeClasspath
org.jetbrains.kotlin:kotlin-scripting-jvm-host:2.0.21=testRuntimeClasspath
org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=testRuntimeOnlyDependenciesMetadata
org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=testRuntimeOnlyDependenciesMetadata
org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,testRuntimeClasspath
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:1.7.10=testRuntimeOnlyDependenciesMetadata
org.jetbrains.kotlin:kotlin-stdlib:2.0.21=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=testRuntimeOnlyDependenciesMetadata
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,testRuntimeClasspath
org.jetbrains:annotations:13.0=compileClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
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.junit.jupiter:junit-jupiter-api:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-api:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-engine:5.8.2=testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.platform:junit-platform-commons:1.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.platform:junit-platform-commons:1.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.platform:junit-platform-engine:1.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.platform:junit-platform-engine:1.8.2=testJdk17RuntimeClasspath
org.junit.platform:junit-platform-launcher:1.8.2=testJdk17RuntimeClasspath
org.junit:junit-bom:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit:junit-bom:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
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.2.0=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.organicdesign:Paguro:3.10.3=runtimeClasspath,testRuntimeClasspath
org.snakeyaml:snakeyaml-engine:2.9=runtimeClasspath,testRuntimeClasspath
empty=annotationProcessor,compileOnlyDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtimeOnlyDependenciesMetadata,signatures,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testJdk17AnnotationProcessor,testJdk17ApiDependenciesMetadata,testJdk17CompileOnlyDependenciesMetadata,testJdk17IntransitiveDependenciesMetadata,testJdk17KotlinScriptDefExtensions,testKotlinScriptDef,testKotlinScriptDefExtensions
org.snakeyaml:snakeyaml-engine:2.10=runtimeClasspath,testRuntimeClasspath
empty=annotationProcessor,compileOnlyDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,shadow,signatures,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions

View File

@@ -17,6 +17,7 @@ plugins {
pklAllProjects
pklKotlinLibrary
pklPublishLibrary
pklJavaExecutable
}
publishing {
@@ -53,3 +54,11 @@ dependencies {
testImplementation(projects.pklCommonsTest)
testRuntimeOnly(libs.kotlinScripting)
}
executable {
javaName = "pkl-codegen-kotlin"
documentationName = "Pkl Codegen Kotlin"
javaPublicationName = "pkl-cli-codegen-kotlin"
mainClass = "org.pkl.codegen.kotlin.Main"
website = "https://pkl-lang.org/main/current/kotlin-binding/codegen.html"
}

View File

@@ -38,6 +38,9 @@ data class CliKotlinCodeGeneratorOptions(
/** Whether generated classes should implement [java.io.Serializable]. */
val implementSerializable: Boolean = false,
/** Whether to add the `@Generated` annotation to types */
val addGeneratedAnnotation: Boolean = false,
/**
* A rename mapping for class names.
*
@@ -57,6 +60,7 @@ data class CliKotlinCodeGeneratorOptions(
generateKdoc,
generateSpringBootConfig,
implementSerializable,
addGeneratedAnnotation,
renames,
)
}

View File

@@ -40,6 +40,9 @@ data class KotlinCodeGeneratorOptions(
/** Whether to generate classes that implement [java.io.Serializable]. */
val implementSerializable: Boolean = false,
/** Whether to add the `@Generated` to generated types. */
val addGeneratedAnnotation: Boolean = false,
/**
* A mapping from Pkl module name prefixes to their replacements.
*
@@ -226,6 +229,9 @@ class KotlinCodeGenerator(
fun PClass.Property.isRegex(): Boolean =
(this.type as? PType.Class)?.pClass?.info == PClassInfo.Regex
fun PClass.Property.isByteArray(): Boolean =
(this.type as? PType.Class)?.pClass?.info == PClassInfo.Bytes
fun generateConstructor(): FunSpec {
val builder = FunSpec.constructorBuilder()
for ((name, property) in allProperties) {
@@ -302,12 +308,20 @@ class KotlinCodeGenerator(
.addStatement("other as %T", kotlinPoetClassName)
for ((propertyName, property) in allProperties) {
val accessor = if (property.isRegex()) "%N.pattern" else "%N"
builder.addStatement(
"if (this.$accessor != other.$accessor) return false",
propertyName,
propertyName,
)
if (property.isByteArray()) {
builder.addStatement(
"if (!this.%N.contentEquals(other.%N)) return false",
propertyName,
propertyName,
)
} else {
val accessor = if (property.isRegex()) "%N.pattern" else "%N"
builder.addStatement(
"if (this.$accessor != other.$accessor) return false",
propertyName,
propertyName,
)
}
}
builder.addStatement("return true")
@@ -322,14 +336,18 @@ class KotlinCodeGenerator(
.addStatement("var result = 1")
for ((propertyName, property) in allProperties) {
val accessor = if (property.isRegex()) "this.%N.pattern" else "this.%N"
// use Objects.hashCode() because Kotlin's Any?.hashCode()
// doesn't work for platform types (will get NPE if null)
builder.addStatement(
"result = 31 * result + %T.hashCode($accessor)",
Objects::class,
propertyName,
)
if (property.isByteArray()) {
builder.addStatement("result = 31 * result + this.%N.contentHashCode()", propertyName)
} else {
val accessor = if (property.isRegex()) "this.%N.pattern" else "this.%N"
// use Objects.hashCode() because Kotlin's Any?.hashCode()
// doesn't work for platform types (will get NPE if null)
builder.addStatement(
"result = 31 * result + %T.hashCode($accessor)",
Objects::class,
propertyName,
)
}
}
builder.addStatement("return result")
@@ -347,10 +365,15 @@ class KotlinCodeGenerator(
.apply {
add("%L", pClass.toKotlinPoetName().simpleName)
add("(")
for ((index, propertyName) in allProperties.keys.withIndex()) {
for ((index, entry) in allProperties.entries.withIndex()) {
val (propertyName, property) = entry
add(if (index == 0) "%L" else ", %L", propertyName)
add("=$")
add("%N", propertyName)
if (property.isByteArray()) {
add("=\${%T.toString(%L)}", Arrays::class, propertyName)
} else {
add("=$")
add("%N", propertyName)
}
}
add(")")
}
@@ -435,6 +458,9 @@ class KotlinCodeGenerator(
if (options.generateSpringBootConfig) {
generateSpringBootAnnotations(builder)
}
if (options.addGeneratedAnnotation) {
builder.addAnnotation(ClassName("org.pkl.config.java", "Generated"))
}
builder.primaryConstructor(generateConstructor())
@@ -478,6 +504,9 @@ class KotlinCodeGenerator(
if (options.generateSpringBootConfig) {
generateSpringBootAnnotations(builder)
}
if (options.addGeneratedAnnotation) {
builder.addAnnotation(ClassName("org.pkl.config.java", "Generated"))
}
builder.primaryConstructor(generateConstructor())
@@ -488,16 +517,16 @@ class KotlinCodeGenerator(
builder.addKdoc(renderAsKdoc(docComment))
}
var hasRegex = false
var hasRegexOrByteArray = false
for ((name, property) in properties) {
hasRegex = hasRegex || property.isRegex()
hasRegexOrByteArray = hasRegexOrByteArray || property.isRegex() || property.isByteArray()
builder.addProperty(generateProperty(name, property))
}
// kotlin.text.Regex (and java.util.regex.Pattern) defines equality as identity.
// To match Pkl semantics and compare regexes by their String pattern,
// override equals and hashCode if the data class has a property of type Regex.
if (hasRegex) {
// Regex and ByteArray define equaltiy as identity.
// To match Pkl semantics, override equals and hashCode if the data class has a property of
// type Regex or ByteArray.
if (hasRegexOrByteArray) {
builder.addFunction(generateEqualsMethod()).addFunction(generateHashCodeMethod())
}
@@ -632,6 +661,7 @@ class KotlinCodeGenerator(
PClassInfo.Float -> DOUBLE
PClassInfo.Duration -> DURATION
PClassInfo.DataSize -> DATA_SIZE
PClassInfo.Bytes -> BYTE_ARRAY
PClassInfo.Pair ->
KOTLIN_PAIR.parameterizedBy(
if (typeArguments.isEmpty()) ANY_NULL else typeArguments[0].toKotlinPoetName(),

View File

@@ -79,6 +79,12 @@ class PklKotlinCodegenCommand : ModulesCommand(name = "pkl-codegen-kotlin", help
)
.flag()
private val addGeneratedAnnotation: Boolean by
option(
names = arrayOf("--add-generated-annotation"),
help = "Whether to add a @Generated annotation to the types to be generated.",
)
.flag()
private val renames: Map<String, String> by
option(
names = arrayOf("--rename"),
@@ -105,6 +111,7 @@ class PklKotlinCodegenCommand : ModulesCommand(name = "pkl-codegen-kotlin", help
generateKdoc = generateKdoc,
generateSpringBootConfig = generateSpringboot,
implementSerializable = implementSerializable,
addGeneratedAnnotation = addGeneratedAnnotation,
renames = renames,
)
CliKotlinCodeGenerator(options).run()

View File

@@ -120,6 +120,7 @@ class KotlinCodeGeneratorTest {
any: Any
nonNull: NonNull
enum: Direction
bytes: Bytes
}
open class Other {
@@ -193,7 +194,6 @@ class KotlinCodeGeneratorTest {
@Test
fun testToString() {
val (_, propertyTypes) = instantiateOtherAndPropertyTypes()
assertThat(propertyTypes.toString())
.isEqualTo(
"""PropertyTypes(boolean=true, int=42, float=42.3, string=string, duration=5.min, """ +
@@ -204,7 +204,8 @@ class KotlinCodeGeneratorTest {
"""set2=[Other(name=pigeon)], map={1=one, 2=two}, map2={one=Other(name=pigeon), """ +
"""two=Other(name=pigeon)}, container={1=one, 2=two}, container2={one=Other(name=pigeon), """ +
"""two=Other(name=pigeon)}, other=Other(name=pigeon), regex=(i?)\w*, any=Other(name=pigeon), """ +
"""nonNull=Other(name=pigeon), enum=north)"""
"""nonNull=Other(name=pigeon), enum=north, """ +
"""bytes=[1, 2, 3, 4])"""
)
}
@@ -412,6 +413,7 @@ class KotlinCodeGeneratorTest {
assertThat(readProperty(propertyTypes, "regex")).isInstanceOf(Regex::class.java)
assertThat(readProperty(propertyTypes, "any")).isEqualTo(other)
assertThat(readProperty(propertyTypes, "nonNull")).isEqualTo(other)
assertThat(readProperty(propertyTypes, "bytes")).isEqualTo(byteArrayOf(1, 2, 3, 4))
}
private fun readProperty(receiver: Any, name: String): Any? {
@@ -571,6 +573,25 @@ class KotlinCodeGeneratorTest {
.contains("result = 31 * result + Objects.hashCode(this.name.pattern)")
}
@Test
fun `data class with ByteArray property has custom equals and hashCode methods`() {
val kotlinCode =
generateKotlinCode(
"""
module my.mod
class Foo {
bytes: Bytes
}
"""
.trimIndent()
)
assertThat(kotlinCode)
.contains("if (!this.bytes.contentEquals(other.bytes)) return false")
.contains("result = 31 * result + this.bytes.contentHashCode()")
}
@Test
fun `recursive types`() {
val kotlinCode =
@@ -2008,6 +2029,30 @@ class KotlinCodeGeneratorTest {
)
}
@Test
fun `add generated annotation`() {
val files =
KotlinCodeGeneratorOptions(addGeneratedAnnotation = true)
.generateFiles("com.example.MyModule" to "foo: String")
assertThat(files).containsKey("kotlin/com/example/MyModule.kt")
assertThat(files["kotlin/com/example/MyModule.kt"])
.isEqualTo(
"""
package com.example
import kotlin.String
import org.pkl.config.java.Generated
@Generated
data class MyModule(
val foo: String
)
"""
.trimIndent()
)
}
private fun Map<String, String>.validateContents(
vararg assertions: kotlin.Pair<String, List<String>>
) {
@@ -2078,6 +2123,7 @@ class KotlinCodeGeneratorTest {
other,
other,
enumValue,
byteArrayOf(1, 2, 3, 4),
)
return other to propertyTypes

View File

@@ -1,8 +1,10 @@
package my
import java.util.Arrays
import java.util.Objects
import kotlin.Any
import kotlin.Boolean
import kotlin.ByteArray
import kotlin.Double
import kotlin.Int
import kotlin.Long
@@ -46,7 +48,8 @@ object Mod {
open val regex: Regex,
open val any: Any?,
open val nonNull: Any,
open val enum: Direction
open val enum: Direction,
open val bytes: ByteArray
) {
open fun copy(
boolean: Boolean = this.boolean,
@@ -75,10 +78,11 @@ object Mod {
regex: Regex = this.regex,
any: Any? = this.any,
nonNull: Any = this.nonNull,
enum: Direction = this.enum
enum: Direction = this.enum,
bytes: ByteArray = this.bytes
): PropertyTypes = PropertyTypes(boolean, int, float, string, duration, durationUnit, dataSize,
dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map,
map2, container, container2, other, regex, any, nonNull, enum)
map2, container, container2, other, regex, any, nonNull, enum, bytes)
override fun equals(other: Any?): Boolean {
if (this === other) return true
@@ -111,6 +115,7 @@ object Mod {
if (this.any != other.any) return false
if (this.nonNull != other.nonNull) return false
if (this.enum != other.enum) return false
if (!this.bytes.contentEquals(other.bytes)) return false
return true
}
@@ -143,11 +148,12 @@ object Mod {
result = 31 * result + Objects.hashCode(this.any)
result = 31 * result + Objects.hashCode(this.nonNull)
result = 31 * result + Objects.hashCode(this.enum)
result = 31 * result + this.bytes.contentHashCode()
return result
}
override fun toString(): String =
"""PropertyTypes(boolean=$boolean, int=$int, float=$float, string=$string, duration=$duration, durationUnit=$durationUnit, dataSize=$dataSize, dataSizeUnit=$dataSizeUnit, nullable=$nullable, nullable2=$nullable2, pair=$pair, pair2=$pair2, coll=$coll, coll2=$coll2, list=$list, list2=$list2, set=$set, set2=$set2, map=$map, map2=$map2, container=$container, container2=$container2, other=$other, regex=$regex, any=$any, nonNull=$nonNull, enum=$enum)"""
"""PropertyTypes(boolean=$boolean, int=$int, float=$float, string=$string, duration=$duration, durationUnit=$durationUnit, dataSize=$dataSize, dataSizeUnit=$dataSizeUnit, nullable=$nullable, nullable2=$nullable2, pair=$pair, pair2=$pair2, coll=$coll, coll2=$coll2, list=$list, list2=$list2, set=$set, set2=$set2, map=$map, map2=$map2, container=$container, container2=$container2, other=$other, regex=$regex, any=$any, nonNull=$nonNull, enum=$enum, bytes=${Arrays.toString(bytes)})"""
}
open class Other(

View File

@@ -23,14 +23,23 @@ com.github.ajalt.mordant:mordant-markdown:3.0.1=compileClasspath,implementationD
com.github.ajalt.mordant:mordant:3.0.1=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
net.bytebuddy:byte-buddy:1.15.11=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
net.java.dev.jna:jna:5.14.0=runtimeClasspath,testRuntimeClasspath
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata,testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
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=runtimeClasspath,testRuntimeClasspath
org.graalvm.sdk:collections:24.1.2=runtimeClasspath,testRuntimeClasspath
org.graalvm.sdk:graal-sdk:24.1.2=runtimeClasspath,testRuntimeClasspath
org.graalvm.sdk:nativeimage:24.1.2=runtimeClasspath,testRuntimeClasspath
org.graalvm.sdk:word:24.1.2=runtimeClasspath,testRuntimeClasspath
org.graalvm.truffle:truffle-api:24.1.2=runtimeClasspath,testRuntimeClasspath
org.graalvm.compiler:compiler:24.1.2=svmClasspath
org.graalvm.nativeimage:native-image-base:24.1.2=svmClasspath
org.graalvm.nativeimage:objectfile:24.1.2=svmClasspath
org.graalvm.nativeimage:pointsto:24.1.2=svmClasspath
org.graalvm.nativeimage:svm:24.1.2=svmClasspath
org.graalvm.nativeimage:truffle-runtime-svm:24.1.2=svmClasspath
org.graalvm.polyglot:polyglot:24.1.2=runtimeClasspath,svmClasspath,testRuntimeClasspath
org.graalvm.sdk:collections:24.1.2=runtimeClasspath,svmClasspath,testRuntimeClasspath
org.graalvm.sdk:graal-sdk:24.1.2=runtimeClasspath,svmClasspath,testRuntimeClasspath
org.graalvm.sdk:jniutils:24.1.2=svmClasspath
org.graalvm.sdk:nativeimage:24.1.2=runtimeClasspath,svmClasspath,testRuntimeClasspath
org.graalvm.sdk:word:24.1.2=runtimeClasspath,svmClasspath,testRuntimeClasspath
org.graalvm.truffle:truffle-api:24.1.2=runtimeClasspath,svmClasspath,testRuntimeClasspath
org.graalvm.truffle:truffle-compiler:24.1.2=svmClasspath
org.graalvm.truffle:truffle-runtime:24.1.2=svmClasspath
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
@@ -42,35 +51,27 @@ org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=kotlinBuildToolsApiClasspat
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,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinCompilerPluginClasspathTestJdk17
org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathSvm,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathSvm,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathSvm,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathSvm,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathSvm,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,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:2.0.21=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathSvm,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,kotlinCompilerPluginClasspathTestJdk17,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.jetbrains:annotations:13.0=compileClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathSvm,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.jetbrains:markdown-jvm:0.7.3=runtimeClasspath,testRuntimeClasspath
org.jetbrains:markdown:0.7.3=implementationDependenciesMetadata,runtimeClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-api:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-api:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-engine:5.8.2=testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.jupiter:junit-jupiter:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.platform:junit-platform-commons:1.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.platform:junit-platform-commons:1.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.junit.platform:junit-platform-engine:1.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.platform:junit-platform-engine:1.8.2=testJdk17RuntimeClasspath
org.junit.platform:junit-platform-launcher:1.8.2=testJdk17RuntimeClasspath
org.junit:junit-bom:5.11.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit:junit-bom:5.8.2=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.msgpack:msgpack-core:0.9.8=runtimeClasspath,testRuntimeClasspath
org.opentest4j:opentest4j:1.2.0=testJdk17CompileClasspath,testJdk17ImplementationDependenciesMetadata,testJdk17RuntimeClasspath
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.organicdesign:Paguro:3.10.3=runtimeClasspath,testRuntimeClasspath
org.snakeyaml:snakeyaml-engine:2.9=runtimeClasspath,testRuntimeClasspath
empty=annotationProcessor,compileOnlyDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtimeOnlyDependenciesMetadata,signatures,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testJdk17AnnotationProcessor,testJdk17ApiDependenciesMetadata,testJdk17CompileOnlyDependenciesMetadata,testJdk17IntransitiveDependenciesMetadata,testJdk17KotlinScriptDefExtensions,testKotlinScriptDef,testKotlinScriptDefExtensions
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,svmClasspath,testRuntimeClasspath
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.organicdesign:Paguro:3.10.3=runtimeClasspath,svmClasspath,testRuntimeClasspath
org.snakeyaml:snakeyaml-engine:2.10=runtimeClasspath,svmClasspath,testRuntimeClasspath
empty=annotationProcessor,compileOnlyDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,signatures,sourcesJar,svmAnnotationProcessor,svmApiDependenciesMetadata,svmCompileClasspath,svmCompileOnlyDependenciesMetadata,svmImplementationDependenciesMetadata,svmIntransitiveDependenciesMetadata,svmKotlinScriptDefExtensions,svmRuntimeClasspath,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions

View File

@@ -19,6 +19,11 @@ plugins {
pklPublishLibrary
}
val svmClasspath: Configuration by configurations.creating
// used by pklNativeExecutable.gradle.kts
@Suppress("unused") val svm: SourceSet by sourceSets.creating { compileClasspath = svmClasspath }
dependencies {
api(projects.pklCore)
api(libs.clikt)
@@ -26,6 +31,10 @@ dependencies {
implementation(projects.pklCommons)
testImplementation(projects.pklCommonsTest)
svmClasspath(libs.svm)
svmClasspath(libs.truffleSvm)
svmClasspath(projects.pklCore)
}
publishing {

View File

@@ -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.
@@ -140,6 +140,9 @@ data class CliBaseOptions(
/** Hostnames, IP addresses, or CIDR blocks to not proxy. */
val httpNoProxy: List<String>? = null,
/** URL prefixes to rewrite. */
val httpRewrites: Map<URI, URI>? = null,
/** External module reader process specs */
val externalModuleReaders: Map<String, ExternalReader> = mapOf(),

View File

@@ -15,6 +15,7 @@
*/
package org.pkl.commons.cli
import java.net.URI
import java.nio.file.Files
import java.nio.file.Path
import java.util.regex.Pattern
@@ -166,29 +167,36 @@ abstract class CliCommand(protected val cliOptions: CliBaseOptions) {
protected val useColor: Boolean by lazy { cliOptions.color?.hasColor() ?: false }
private val proxyAddress by lazy {
private val proxyAddress: URI? by lazy {
cliOptions.httpProxy
?: project?.evaluatorSettings?.http?.proxy?.address
?: settings.http?.proxy?.address
}
private val noProxy by lazy {
private val noProxy: List<String>? by lazy {
cliOptions.httpNoProxy
?: project?.evaluatorSettings?.http?.proxy?.noProxy
?: settings.http?.proxy?.noProxy
}
private val externalModuleReaders by lazy {
private val httpRewrites: Map<URI, URI>? by lazy {
cliOptions.httpRewrites
?: project?.evaluatorSettings?.http?.rewrites
?: settings.http?.rewrites()
}
private val externalModuleReaders: Map<String, PklEvaluatorSettings.ExternalReader> by lazy {
(project?.evaluatorSettings?.externalModuleReaders ?: emptyMap()) +
cliOptions.externalModuleReaders
}
private val externalResourceReaders by lazy {
private val externalResourceReaders: Map<String, PklEvaluatorSettings.ExternalReader> by lazy {
(project?.evaluatorSettings?.externalResourceReaders ?: emptyMap()) +
cliOptions.externalResourceReaders
}
private val externalProcesses by lazy {
private val externalProcesses:
Map<PklEvaluatorSettings.ExternalReader, ExternalReaderProcess> by lazy {
// Share ExternalReaderProcess instances between configured external resource/module readers
// with the same spec. This avoids spawning multiple subprocesses if the same reader implements
// both reader types and/or multiple schemes.
@@ -232,6 +240,7 @@ abstract class CliCommand(protected val cliOptions: CliBaseOptions) {
if ((proxyAddress ?: noProxy) != null) {
setProxy(proxyAddress, noProxy ?: listOf())
}
httpRewrites?.let(::setRewrites)
// Lazy building significantly reduces execution time of commands that do minimal work.
// However, it means that HTTP client initialization errors won't surface until an HTTP
// request is made.

View File

@@ -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.
@@ -17,4 +17,9 @@ package org.pkl.commons.cli
import java.nio.file.Path
class CliTestOptions(val junitDir: Path? = null, val overwrite: Boolean = false)
class CliTestOptions(
val junitDir: Path? = null,
val overwrite: Boolean = false,
val junitAggregateReports: Boolean = false,
val junitAggregateSuiteName: String = "pkl-tests",
)

View File

@@ -15,6 +15,7 @@
*/
package org.pkl.commons.cli.commands
import com.github.ajalt.clikt.completion.CompletionCandidates
import com.github.ajalt.clikt.parameters.groups.OptionGroup
import com.github.ajalt.clikt.parameters.options.*
import com.github.ajalt.clikt.parameters.types.enum
@@ -165,6 +166,7 @@ class BaseOptions : OptionGroup() {
option(
names = arrayOf("-f", "--format"),
help = "Output format to generate. <${output.joinToString()}>",
completionCandidates = CompletionCandidates.Fixed(output.toSet()),
)
.single()
@@ -187,9 +189,13 @@ class BaseOptions : OptionGroup() {
.splitAll(File.pathSeparator)
val settings: URI? by
option(names = arrayOf("--settings"), help = "Pkl settings module to use.").single().convert {
parseModuleName(it)
}
option(
names = arrayOf("--settings"),
help = "Pkl settings module to use.",
completionCandidates = CompletionCandidates.Path,
)
.single()
.convert { parseModuleName(it) }
val timeout: Duration? by
option(
@@ -235,6 +241,39 @@ class BaseOptions : OptionGroup() {
.single()
.split(",")
val httpRewrites: Map<URI, URI> by
option(
names = arrayOf("--http-rewrite"),
metavar = "from=to",
help = "URL prefixes that should be rewritten.",
)
.convert { it ->
val uris = it.split("=", limit = 2)
require(uris.size == 2) { "Rewrites must be in the form of <from>=<to>" }
try {
val (fromSpec, toSpec) = uris
val fromUri = URI(fromSpec).also { IoUtils.validateRewriteRule(it) }
val toUri = URI(toSpec).also { IoUtils.validateRewriteRule(it) }
fromUri to toUri
} catch (e: IllegalArgumentException) {
fail(e.message!!)
} catch (e: URISyntaxException) {
val message = buildString {
append("Rewrite target `${e.input}` has invalid syntax (${e.reason}).")
if (e.index > -1) {
append("\n\n")
append(e.input)
append("\n")
append(" ".repeat(e.index))
append("^")
}
}
fail(message)
}
}
.multiple()
.toMap()
val externalModuleReaders: Map<String, ExternalReader> by
option(
names = arrayOf("--external-module-reader"),
@@ -288,7 +327,8 @@ class BaseOptions : OptionGroup() {
noProject = projectOptions?.noProject ?: false,
caCertificates = caCertificates,
httpProxy = proxy,
httpNoProxy = noProxy ?: emptyList(),
httpNoProxy = noProxy,
httpRewrites = httpRewrites.ifEmpty { null },
externalModuleReaders = externalModuleReaders,
externalResourceReaders = externalResourceReaders,
)

View File

@@ -15,6 +15,7 @@
*/
package org.pkl.commons.cli.commands
import com.github.ajalt.clikt.completion.CompletionCandidates
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.convert
import com.github.ajalt.clikt.parameters.arguments.multiple
@@ -24,7 +25,11 @@ import java.net.URI
abstract class ModulesCommand(name: String, helpLink: String) :
BaseCommand(name = name, helpLink = helpLink) {
open val modules: List<URI> by
argument(name = "modules", help = "Module paths or URIs to evaluate.")
argument(
name = "modules",
help = "Module paths or URIs to evaluate.",
completionCandidates = CompletionCandidates.Path,
)
.convert { BaseOptions.parseModuleName(it) }
.multiple(required = true)

View File

@@ -16,6 +16,7 @@
package org.pkl.commons.cli.commands
import com.github.ajalt.clikt.parameters.groups.OptionGroup
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.types.path
@@ -31,8 +32,26 @@ class TestOptions : OptionGroup() {
)
.path()
private val junitAggregateReports: Boolean by
option(
names = arrayOf("--junit-aggregate-reports"),
help = "Aggregate JUnit reports into a single file.",
)
.flag()
private val junitAggregateSuiteName: String by
option(
names = arrayOf("--junit-aggregate-suite-name"),
metavar = "name",
help = "The name of the root JUnit test suite.",
)
.single()
.default("pkl-tests")
private val overwrite: Boolean by
option(names = arrayOf("--overwrite"), help = "Force generation of expected examples.").flag()
val cliTestOptions: CliTestOptions by lazy { CliTestOptions(junitReportDir, overwrite) }
val cliTestOptions: CliTestOptions by lazy {
CliTestOptions(junitReportDir, overwrite, junitAggregateReports, junitAggregateSuiteName)
}
}

View File

@@ -30,7 +30,11 @@ private val theme = Theme { styles["markdown.code.span"] = TextStyle(bold = true
fun <T : BaseCliktCommand<T>> T.installCommonOptions() {
installMordantMarkdown()
versionOption(Release.current().versionInfo, names = setOf("-v", "--version"), message = { it })
versionOption(
Release.current().versionInfo,
names = setOf("-v", "--version"),
message = { if (commandName == "pkl") it else it.replaceFirst("Pkl", commandName) },
)
context { terminal = Terminal(theme = theme) }
}

View File

@@ -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.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.pkl.cli.svm;
package org.pkl.commons.cli.svm;
import org.graalvm.nativeimage.hosted.Feature;
import org.pkl.core.runtime.BaseModule;

View File

@@ -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.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.pkl.cli.svm;
package org.pkl.commons.cli.svm;
import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.RecomputeFieldValue;

Some files were not shown because too many files have changed in this diff Show More