mirror of
https://github.com/apple/pkl.git
synced 2026-01-11 22:30:54 +01:00
421 lines
15 KiB
Plaintext
421 lines
15 KiB
Plaintext
= 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]]
|
|
=== 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]
|