384 Commits
0.26.2 ... main

Author SHA1 Message Date
Akshat Anand
9d385f2194 Fix super method call inside let expression (#1383)
Fixes #1309

The issue was that super calls were blocked inside let expressions
because:
1. The compiler's isClassMemberScope() check didn't skip over lambda
scopes created by let expressions
2. The runtime's findSupermethod() didn't traverse past VmFunction
owners to find the actual class prototype

Changes:
- SymbolTable.java: Updated isClassMemberScope() to skip lambda scopes
before checking if the parent is a class or module scope
- InvokeSuperMethodNode.java: Updated findSupermethod() to skip
VmFunction owners when looking for the class prototype

Added regression tests covering:
- Super method calls inside let expressions
- Super property access inside let expressions
- Nested let expressions with super calls

---------

Co-authored-by: Jen Basch <jbasch@apple.com>
2026-01-09 19:59:20 -08:00
Jen Basch
3595c03078 Fix spotless ratcheting on release branches (#1401) 2026-01-09 14:18:18 -08:00
Jen Basch
9b6f72d5d0 Fix doc links from pkl:base to pkl:math (#1400) 2026-01-09 11:30:56 -08:00
Daniel Chao
ac4f2fd9a6 Add isNotEmpty, isNotBlank methods (#1396)
Adds convenience methods `isNotEmpty` and `isNotBlank`. This borrows the
same methods from Kotlin.

This helps users write more fluent constraints, for example,
`foo.isNotEmpty.implies(bar)`.

Adds:

* List#isNotEmpty
* Map#isNotEmpty
* Set#isNotEmpty
* Mapping#isNotEmpty
* Listing#isNotEmpty
* String#isNotEmpty
* String#isNotBlank
2026-01-08 13:22:43 -08:00
Daniel Chao
14d58a17b0 Address warning diagnostics (#1395)
This addressess various warning diagnostics throughout the codebase.
2026-01-07 22:11:24 -08:00
Daniel Chao
474305c7b9 Use gradle/actions/setup-gradle (#1397)
This adds the setup-gradle action; which has the following improvements:

* Improved cacheing (compared to setup-java's Gradle cache)
* Validates the gradle wrapper jar
2026-01-07 21:10:07 -08:00
Daniel Chao
6b9c670cfd Add syntax highlighting of Pkl code (#1385)
This adds syntax highlighting of Pkl code!

It adds highlighting for:

* Stack frames within error messages
* CLI REPL (highlights as you type, highlights error output)
* Power assertions (coming in https://github.com/apple/pkl/pull/1384)

This uses the lexer for highlighting. It will highlight strings,
numbers, keywords, but doesn't understand how to highlight nodes like
types, function params, etc.
The reason for this is because a single line of code by itself may not
be grammatically valid.
2026-01-06 10:33:11 -08:00
Daniel Chao
4f4f03dbca Fix cacheing of module type (#1393)
This fixes an issue where the `module` type is incorrectly cached.
2026-01-05 14:49:07 -08:00
Eduardo Aguilar Moreno
6cd03c7f56 Add pkl bom module (#1390)
This adds a module that will publish a bom file that will help consumers
align versions for all pkl artifacts using the single bom.
2026-01-05 14:47:28 -08:00
Daniel Chao
8f83885c75 Fix default value for non-final module type (#1392)
This fixes an issue where the `module` type produces the wrong default
value.

Closes #1391
2026-01-05 11:39:24 -08:00
Stefan M.
0a4281366f Do not throw if output dir is symlink (#1389) 2026-01-05 10:16:32 -08:00
dependabot[bot]
35861240a0 Bump EnricoMi/publish-unit-test-result-action from 2.21.0 to 2.22.0 (#1382)
Bumps
[EnricoMi/publish-unit-test-result-action](https://github.com/enricomi/publish-unit-test-result-action)
from 2.21.0 to 2.22.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/enricomi/publish-unit-test-result-action/releases">EnricoMi/publish-unit-test-result-action's
releases</a>.</em></p>
<blockquote>
<h2>v2.22.0</h2>
<p>Adds the following improvements:</p>
<ul>
<li>Upgrade all Python dependencies to latest version <a
href="https://redirect.github.com/enricomi/publish-unit-test-result-action/issues/710">#710</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/EnricoMi/publish-unit-test-result-action/compare/v2.21.0...v2.22.0">https://github.com/EnricoMi/publish-unit-test-result-action/compare/v2.21.0...v2.22.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="27d65e188e"><code>27d65e1</code></a>
Releasing v2.22.0</li>
<li><a
href="2deae407d7"><code>2deae40</code></a>
Upgrade transient dependencies (<a
href="https://redirect.github.com/enricomi/publish-unit-test-result-action/issues/710">#710</a>)</li>
<li><a
href="a6d8f3d6ca"><code>a6d8f3d</code></a>
Add Ubuntu slim runner (<a
href="https://redirect.github.com/enricomi/publish-unit-test-result-action/issues/709">#709</a>)</li>
<li><a
href="d3ed9acf9b"><code>d3ed9ac</code></a>
CI: Merge check upgrades jobs into single job (<a
href="https://redirect.github.com/enricomi/publish-unit-test-result-action/issues/700">#700</a>)</li>
<li>See full diff in <a
href="34d7c956a5...27d65e188e">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=EnricoMi/publish-unit-test-result-action&package-manager=github_actions&previous-version=2.21.0&new-version=2.22.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-22 09:34:57 -08:00
Daniel Chao
3f4e894e43 Import release notes from 0.30.2 (#1375) 2025-12-15 13:14:18 -08:00
Daniel Chao
dcf3f24e3b Sort list of repos alphabetically (#1376) 2025-12-15 12:48:26 -08:00
Daniel Chao
6614cf11fb Add highlight.js and pkl-readers repo entries to README (#1371)
Co-authored-by: Jen Basch <jbasch94@gmail.com>
2025-12-15 11:28:30 -08:00
Daniel Chao
b92c773555 Bump pkl.impl.ghactions (#1366) 2025-12-12 11:30:47 -08:00
Daniel Chao
f528927797 Fix building of pkl-doc (#1365)
Ensure that `assembleNative` is called before testing the native
executable
2025-12-12 09:36:38 -08:00
Islon Scherer
41cf485ffb Fix bug in parsing of super expression (#1364) 2025-12-12 18:02:48 +01:00
Daniel Chao
cd9cfaae8f Bump pkl.impl.ghactions, update lockfile to not run (#1362) 2025-12-10 21:39:18 -08:00
Daniel Chao
2578703081 Bump versions, fix dependabot updates (#1361) 2025-12-10 18:03:32 -08:00
Daniel Chao
b170968e9e Bump pkl.impl.ghactions to 1.1.0, add version locking. (#1359)
This adopts the version locking introduced in pkl.impl.ghactions@1.1.0.
2025-12-10 16:35:15 -08:00
Daniel Chao
32e9087da9 Fix formatting of nodes with no children (#1351)
For example, this fixes an issue where an empty module turns into ` \n`.

Closes https://github.com/apple/pkl/issues/1348

---------

Co-authored-by: Jen Basch <jbasch94@gmail.com>
2025-12-09 11:03:50 -08:00
Daniel Chao
9d41518553 Bump pkl.impl.ghactions to 1.0.1 (#1358) 2025-12-09 10:53:04 -08:00
Daniel Chao
b7ccc67bd8 Adjust CI to not publish test results for deploy-snapshot (#1357) 2025-12-08 09:56:57 -08:00
Daniel Chao
252f44728e Adjust native lifecycle builds to not throw during configuration phase (#1356)
Allow Gradle to run other tasks on unsupported machines, but throw when
running native lifecycle tasks (e.g. `buildNative`).
2025-12-07 11:35:14 -08:00
Jen Basch
139f70bb79 Change pkl format --write to exit 0 when formatting violations are found (#1340) 2025-12-05 16:01:09 -08:00
Daniel Chao
2de1d5b9d2 Build linux executables that link to glibc 2.17 (#1352)
Fixes an unintentional breakage in 0.30.1 that bumped the required glibc to 2.34.
2025-12-05 15:24:27 -08:00
Jen Basch
81a4e687b4 Fix IDEA gradle project sync on Windows Aarch64 (#1353) 2025-12-05 14:53:06 -08:00
Daniel Chao
e1559c66ad Fix CI build for pkldoc (#1349)
Fixes an issue where the executable is not built.

Haven't dug into why this broke; this was working just a little bit ago
(see
https://github.com/apple/pkl/actions/runs/19911073549/job/57079605641?pr=1342).
Nevertheless, the lifecycle job dependencies were a little wonky (test
should assemble first).

[native-pkl-doc]
2025-12-05 09:54:57 -08:00
Daniel Chao
c2d672e943 Omit superfluous newline when writing formatted content to stdout (#1350)
Fixes an issue where an extra newline is added when writing formatted
code to stdout.

Closes https://github.com/apple/pkl/issues/1346
2025-12-05 09:54:31 -08:00
Jen Basch
1d94ab5c3c Prepare 0.30.1 release (#1345) 2025-12-03 21:13:36 -08:00
Jen Basch
c73fc87583 Fix release publishing (#1343) 2025-12-03 15:13:31 -08:00
Daniel Chao
bcbe1b8995 Fix testing of pkldoc executables (#1342)
These tests are actually not running right now.
2025-12-03 15:12:08 -08:00
Daniel Chao
c5b98d6510 CI job polish (#1341)
Avoids issues where setup-java post-task cacheing will hang with "device
or resource busy".
2025-12-03 15:11:33 -08:00
Jen Basch
db6ff394d7 Fix fetch depth for gradle-compatibility and java-executables-* CI jobs (#1339) 2025-12-03 10:34:03 -08:00
Daniel Chao
53f3be64f3 Fix parsing of URLs with plus signs (#1335)
This fixes an issue where URLs with schemes that contain `+`, `-`, and
`.` would not be parsed correctly.

For example, `foo+bar:///?baz.pkl` would turn into
`foo+bar:///%3Fbaz.pkl`. The query param is lost, and turned into the
path.
2025-12-03 10:11:23 -08:00
Jen Basch
d1c652f736 Vendor paguro's RrbTree, fix an int overflow breaking large Lists (#1337) 2025-12-03 09:02:17 -08:00
Islon Scherer
6c3683c55e Fix snapshot publishing (#1330) 2025-11-26 09:17:14 +01:00
Spencer Phillip Young
cc02b6b685 Fix newline checks in parser (#1328) 2025-11-24 14:40:54 +01:00
Jen Basch
f4938dccca Add support for evaluating module output and expressions to ConfigEvaluator (#1297) 2025-11-19 15:47:12 -08:00
Jen Basch
67f1ff5ab8 Update CLI docs to clarify that --version only applies to the root command (#1326) 2025-11-18 21:08:03 -08:00
Spencer Phillip Young
ba281e8475 Fix empty parenthesized type unexpected error (#1323) 2025-11-18 15:35:44 +01:00
Daniel Chao
bc5d675b6e Fix macos/amd64 image builds (#1322) 2025-11-17 12:16:28 -08:00
Daniel Chao
a2cc70ae37 Fix deploy jobs (#1319)
Specify `merge-multiple` to prevent new directories from being created
when downloading artifacts.
2025-11-15 16:30:51 -08:00
Daniel Chao
0ff99d31c9 Replace broken references to CircleCI (#1318) 2025-11-14 15:44:59 -08:00
Daniel Chao
ef9b53be98 Fix release builds (#1317)
In order to preserve the folder hierarchy in our uploaded artifact,
we need to insert a wildcard in the root path.

Also, fix fan-in of tasks that lead to the publish test result task.
2025-11-14 15:18:30 -08:00
Daniel Chao
0ff9125062 Fix build java executable (#1316) 2025-11-13 17:46:35 -08:00
Daniel Chao
f948ba2a20 Switch to GitHub Actions (#1315)
This switches our builds over to GitHub Actions!

TODO:

* Add macOS/amd64 native-image builds; this isn't working right now
* Patch musl with security patches
* Add benchmark jobs over time

As part of this build, PRBs will now only run `./gradlew check` on Linux,
but other jobs can be run using slash commands, e.g. `[windows]`
to run `./gradle check` on Windows.
2025-11-13 16:03:05 -08:00
Islon Scherer
ecf2d8ba33 Fix Map formatting (#1312) 2025-11-11 09:37:09 +01:00
Daniel Chao
445d94ccff Improve plugin logic (#1296) 2025-11-04 07:33:54 -08:00
Daniel Chao
9e1303ed57 Disable spotless ratcheting of Pkl sources (#1295)
This causes spotless to _always_ format Pkl files, instead of only
formatting them if there's a diff between the file and what's in main.

This means that formatting changes in pkl-formatter will be propagated
to the standard library.
2025-11-04 05:31:49 -08:00
Dan Chao
4c13952b64 Apply spotless formatting 2025-11-03 12:26:58 -08:00
Dan Chao
4d70baba86 Start next dev iteration 2025-11-03 12:26:58 -08:00
Dan Chao
7f231cd916 Prepare 0.30.0 release 2025-11-03 12:26:58 -08:00
Jen Basch
5c944600fa Use 2xlarge resource class for gradle check in CI (#1291) 2025-11-03 10:31:16 -08:00
Islon Scherer
5030061412 Fix ordering issue in formatter (#1289) 2025-11-03 18:52:38 +01:00
Daniel Chao
219e766003 Make format command write relative paths (#1290) 2025-11-03 09:52:29 -08:00
Daniel Chao
d29ae07e14 Fix formatting of argument lists (#1283)
This fixes several issues:

1. Leading/trailing line comments surrounding a lambda should make that
   lambda not "trailing", because the formatting otherwise looks bad and
   also isn't stable
2. Fix incorrect algorithm for detecting trailing lambda (currently,
   any number of lambdas makes the alg return `true`)
2025-11-03 09:15:58 -08:00
Islon Scherer
4226c21a42 Fix multiline string stability (#1287) 2025-11-03 17:41:43 +01:00
Daniel Chao
40c88930c5 Normalize paths in pkl format (#1286) 2025-11-03 08:24:04 -08:00
Daniel Chao
d5beb3f331 Fix flag name (#1285) 2025-11-03 08:23:35 -08:00
Daniel Chao
d8adb28dd1 Respect line breaks in operator chains and argument lists (#1268)
If an operator chain or method call is multiline, keep those newlines
in the formatted output.

Help preserve code like:

```
foo
  |> (it) -> it + 2
  |> (it) -> it / 2
```
2025-11-02 21:51:37 -08:00
Daniel Chao
85529c9b7e Add debug and run button for snippet tests (#1281) 2025-10-31 12:28:03 -07:00
Islon Scherer
50541d9cda Make formatter stable (#1273) 2025-10-31 18:58:22 +01:00
Daniel Chao
ea778a7e7a Don't force multiline interpolation into a single line (#1280)
Also, fixes an issue where forced single-line formatting would break for if/else
and let expressions

---------

Co-authored-by: Islon Scherer <islonscherer@gmail.com>
2025-10-31 10:47:53 -07:00
Jen Basch
ffc9167bf5 Switch yaml.Parser to parse binary scalars as Bytes (#1277) 2025-10-30 16:45:59 -07:00
Daniel Chao
ede48d0fff Fix pkl spotless (#1279) 2025-10-30 16:17:08 -07:00
Jen Basch
eab71229e7 Add support for rendering Bytes values with YamlRenderer (#1276) 2025-10-30 15:53:43 -07:00
Daniel Chao
10eccb100c Fix Pkl spotless formatting (#1278) 2025-10-30 15:36:30 -07:00
Jen Basch
2c18f13d08 Rename Config.from to Config.fromPklBinary (#1275) 2025-10-30 11:04:03 -07:00
Jen Basch
9427387019 Add release notes for 0.30 (#1261)
Co-authored-by: Dan Chao <dan.chao@apple.com>
2025-10-30 10:09:35 -07:00
Islon Scherer
db800d4521 Fix trailing lambda ending wrap (#1274) 2025-10-30 17:06:09 +01:00
Jen Basch
08c414f3ac Normalize mutli-line string indentation (#1271) 2025-10-30 08:30:30 -07:00
Islon Scherer
9469dd885d Handle trailing commas in types (#1272) 2025-10-30 13:36:56 +01:00
Islon Scherer
7df447924e Coalesce pkl format subcommands into the parent command. (#1263) 2025-10-30 10:08:25 +01:00
Jen Basch
7bf150055c Assert that formatter snippet test output is stable (#1270) 2025-10-29 17:08:43 -07:00
Jen Basch
1d6261b263 Correctly handle trailing commas in function type literals in the generic parser (#1267) 2025-10-29 15:08:26 -07:00
Islon Scherer
72874ec34a Get style guide in line with formatter (#1265) 2025-10-29 16:00:05 +01:00
Islon Scherer
28c20a8652 Don't break lines in module name (#1266) 2025-10-29 15:24:08 +01:00
Daniel Chao
bbeeffdd32 Adjust formatting of line comments in lets (#1256) 2025-10-28 17:53:06 -07:00
Daniel Chao
825fcf5d1d Respect newlines in if/else and let expressions (#1259)
Change the formatter to prevent multiline if/else and let expressions
from collapsing into a single line.
2025-10-28 11:26:31 -07:00
Daniel Chao
fbcf83aa76 Adjust formatting of argument lists (#1260)
This changes code so that multiple lambda arguments makes the whole
argument list wrap.

Improves the readability of code like:

```
foo
  .toMap(
    (it) -> makeSomeKey(it),
    (it) -> makeSomeValue(it)
  )
```
2025-10-28 10:46:19 -07:00
Islon Scherer
be0142d46b Add grammar compatibility option to the formatter (#1249) 2025-10-28 13:29:08 +01:00
Daniel Chao
ef4989aa35 Wrap comments in base.pkl to 100 chars (#1258)
Also, strip line numbers from reflectedDeclaration.pcf
2025-10-27 16:00:48 -07:00
Daniel Chao
1a25e044ac Polish documentation for pkl-binary (#1250) 2025-10-26 21:23:57 -07:00
Spencer Phillip Young
fdb2bd8c75 Fix Lexer EOF sentinel collision with valid Unicode code points (#1251)
Fixes an issue where sentinel value (U+7FFF) occurring literally in the source could cause a premature termination of parsing, leading to potential EOF injection attacks.

---------

Co-authored-by: Dan Chao <dan.chao@apple.com>
2025-10-26 15:53:48 -07:00
Daniel Chao
a8f76d6209 Adjust formatting of qualified access chains (#1252)
This adjusts formatting of qualified access chains so that leading
dot calls are kept in the same line if possible.
2025-10-24 16:48:21 -07:00
Daniel Chao
c7680aea1f Enforce Pkl formatting of stdlib with spotless (#1253)
This adds a spotless formatting step using the new pkl formatter.

This only formats Pkl sources in the stdlib, because other sources
are possibly test input and not meant to be formatted.
2025-10-24 10:15:14 -07:00
Daniel Chao
3223083324 Format interpolated expressions as single line (#1247)
This forces iterpolated expressions to be single-line, so that newline
literals within the bounds of two string delimiters can be seen as
verbatime newlines in the resulting string.

Edge case: in the case of a line comment, it's not possible to keep
this as a single line expression.
These are kept as multi-line expressions.

Also:

* Remove `ForceWrap`, this node is not used.
* Rename `StringConstant` -> `StringChars`
2025-10-24 03:23:41 -07:00
Daniel Chao
cce49a40fa Add internal intellij plugin (#1248)
This introduces an IntelliJ plugin that's meant to assist with development of the Pkl codebase itself.

The plugin adds a file editor that opens snippet tests in a split editor pane, showing the input on the left side and output on the right side.
2025-10-21 03:42:21 -07:00
Islon Scherer
f6d3fb1228 Fix let formatting (#1246) 2025-10-21 09:45:27 +02:00
Jen Basch
6c036bf82a Implement Pkl binary renderer and parser (#1203)
Implements a binary renderer for Pkl values, which is a lossless capturing of Pkl data.

This follows the pkl binary format that is already used with `pkl server` calls, and is
made available as a Java API and also an in-language API.

Also, introduces a binary parser into the corresponding `PObject` types in Java.
2025-10-20 09:10:22 -07:00
Jen Basch
c602dbb84c Fix macOS Intel native builds (#1244) 2025-10-16 19:20:14 -07:00
Jen Basch
bed008b3da Update macOS release in CI (#1243) 2025-10-16 15:48:23 -07:00
Daniel Chao
80a4dc9617 Fix typos (#1242) 2025-10-16 14:18:49 -07:00
Daniel Chao
b8aad85943 Fix tracking of known usages/subtypes (#1241)
Fixes an issue where known subtype/usage information is not gathered.

Also: change class RuntimeData to not return pairs for better composability.
2025-10-16 12:48:35 -07:00
Daniel Chao
91fec70668 Fix publication of pkl-config-kotlin (#1240)
This fixes a regression where the pkl-config-kotlin library would not
publish after upgrading to Gradle 9.1
2025-10-16 00:44:08 -07:00
Daniel Chao
8c5bd3b7dd Apply pkl formatter to codebase (#1236)
This applies the Pkl formatter to `stdlib/` and `.circleci/`
2025-10-09 15:16:38 -07:00
Daniel Chao
42dcad25c6 Fix error message when reading a resource/module past root dir (#1234) 2025-10-09 10:16:33 -07:00
Daniel Chao
3a29ea8998 Format lambda chains (#1235)
This changes the formatter to only force line on call chains
with multiple lambdas

With this change, this is kept as a single line:

```
foo.bar.map((it) -> it + 1)
```
2025-10-09 10:16:13 -07:00
Daniel Chao
98ab741c54 Bump Kotlin to 2.2.20, minimum Kotlin to 2.1 (#1232)
The current version of the kotlin-gradle plugin is not compatible with
Gradle 9.1, causing error `java.lang.NoSuchMethodError:
 'org.gradle.api.Project org.gradle.api.artifacts.ProjectDependency.getDependencyProject()'`

Also, the Kotlin 2.0 language target is deprecated as of Kotlin 2.2.
2025-10-08 21:40:35 -07:00
Jen Basch
ffa3c14fb3 Pass trace mode from CLI/PklProject to the evaluator (#1230) 2025-10-08 10:49:55 -07:00
Jen Basch
e230fcf1a9 Follow up for trace pretty printing (#1227) 2025-10-08 09:36:42 -07:00
Daniel Chao
cf9d87373d Bump Gradle to 9.1.0 (#1228)
* Bump Gradle to 9.1.0
* Bump foojay resolver to 1.0.0
* Fix build logic on windows

Also, remove support for kotlin gradle plugin less than 1.8.x, because:

* Class `org.gradle.api.plugins.Convention` is no longer available in the classpath in Gradle
* Continued support for legacy plugin would require heavy reflection, which is brittle and hard to verify
* Kotlin 1.7 is 3 years old and no longer updated
2025-10-08 08:54:43 -07:00
Daniel Chao
55eac2088b Bump GraalVM to 25.0.0 (#1226)
* Migrate shadow plugin to org.gradleup to correctly bundle Truffle in
  a fat jar
* Switch to GraalVM Community Edition
2025-10-07 21:23:15 -07:00
Steve Salevan
cecaf39aff Adds traceMode evaluator setting to support trace() pretty printing (#1100) 2025-10-07 12:31:16 -07:00
Daniel Chao
d03a074f63 Bump dependencies (#1225)
* byte-buddy to 1.17.7
* commonmark to 0.26

And also test dependencies (junit, assertj)
2025-10-04 13:59:54 -07:00
Daniel Chao
c585a40601 Fix pkl-doc native test (#1224) 2025-10-03 17:15:14 -07:00
Daniel Chao
2e77d44877 Disable multi-jdk testing when running on Windows ARM (#1223)
Gradle does not support Java toolchains on Windows ARM right now.
To enable running the project in this os/arch, we must omit multi-jdk
test tasks.
2025-10-03 10:36:25 -07:00
Daniel Chao
5d90cf8f4e Introduce pkl-doc model version 2 (#1169)
Currently, in order to update a pkl-doc documentation site,
almost the entire existing site is read in order to update metadata
like known versions, known subtypes, and more.

For example, adding a new version of a package requires that the
existing runtime data of all existing versions be updated.
Eventually, this causes the required storage size to balloon
exponentially to the number of versions.

This addresses these limitations by:

1. Updating the runtime data structure to move "known versions" metadata
   to the package level (the same JSON file is used for all versions).
2. Eliminating known subtype and known usage information at a
   cross-package level.
3. Generating the search index by consuming the previously generated
   search index.
4. Generating the main page by consuming the search index.

Because this changes how runtime data is stored, an existing docsite
needs to be migrated.

This also introduces a new migration command, `pkl-doc --migrate`,
which transforms an older version of the website into a newer version.
2025-09-29 16:10:44 -07:00
Jen Basch
63f89fb679 Expose collected superclass properties/methods in pkl:reflect (#1106) 2025-09-19 12:23:57 -07:00
Simon Rüegg
d1171db3d5 Only format changed files (#1217) 2025-09-19 15:16:32 +02:00
Simon Rüegg
f327c8e086 Allow formatting multiple files/directories (#1215)
This makes it easier to work with tools which return a list of file to
format, e.g. to only handle files which have changed in a PR.
2025-09-19 15:13:22 +02:00
Islon Scherer
618c6243c5 Fix bug in format apply (#1211) 2025-09-19 11:28:40 +02:00
Islon Scherer
222741dccd Fix broken test (#1208) 2025-09-17 13:53:15 -07:00
Islon Scherer
fdc501a35c Implement canonical formatter (#1107)
CLI commands also added: `pkl format check` and `pkl format apply`.
2025-09-17 11:12:04 +02:00
Vladimir Matveev
6a06ab7caa Fixed fallback certificates not working in certain classloader setups (#1198)
In the original implementation the `org/pkl/commons/cli/PklCARoots.pem` resource is resolved relatively to the classloader associated with the class returned by `javaClass`. However, since this is an extension method for `HttpClient.Builder`, it means calling `javaClass` on the builder instance, which is actually defined in the system classpath.

Because of this, if the Pkl class is loaded by a different classloader compared to the one which contains JDK classes, which is totally possible in certain scenarios (e.g. with Gradle), then this resource resolution will fail.

The solution is to resolve `javaClass` against `this@CliCommand`, to use the classloader which loaded the jar with the `CliCommand` class to find the CA resource.
2025-09-04 15:49:43 -07:00
Daniel Chao
a66ac0eb35 Refine documentation for class Any (#1194) 2025-09-02 08:19:39 -07:00
Jen Basch
bef0375285 Improve interrupt handling in pkl repl (#1188) 2025-08-29 13:39:49 -07:00
Jen Basch
44cc154501 Prepare 0.29.1 release (#1192)
Co-authored-by: Daniel Chao <dan.chao@apple.com>
2025-08-27 14:33:25 -07:00
Artem Yarmoliuk
af7057b75f Fix shell completion for paths (#1161) 2025-08-26 10:46:54 -07:00
Jen Basch
a8806416b9 Correctly handle EOF after unmatched backtick (#1187) 2025-08-25 14:31:26 -07:00
Jen Basch
b32039a4f1 Add me as a maintainer (#1185) 2025-08-25 13:17:53 -07:00
Daniel Chao
a779316cc2 Update dependencies (#1184)
Bump test dependencies, and also commonmark
2025-08-21 21:32:56 -07:00
Daniel Chao
d9db939bdc 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-21 06:44:13 -07:00
Jen Basch
ae5f02b285 Allow trailing commas in comma-separated syntax elements (#1137) 2025-08-21 06:43:38 -07:00
Daniel Chao
3f2f0c3a2b Add docs for installing via winget (#1171) 2025-08-11 17:22:30 -07:00
Daniel Chao
7d50aaeec9 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-06 07:57:52 -07:00
Daniel Chao
78ba6bf758 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:43:24 -07:00
Daniel Chao
20e7e251ec 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-07-28 10:13:45 -07:00
Islon Scherer
a3cc2f0ea6 Start next dev iteration 2025-07-24 20:06:01 +02:00
Islon Scherer
e12c655f5c Prepare 0.29.0 release 2025-07-24 20:06:01 +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
Daniel Chao
cf889246fd Add release notes for 0.28 (#978)
Co-authored-by: Islon Scherer <islonscherer@gmail.com>
2025-02-26 07:52:21 -08:00
Daniel Chao
fcce5c7e11 Replace dead links to ANTLR parser grammar (#973) 2025-02-21 08:26:49 -08:00
odenix
52a86d3f32 Untangle external reader code (#776)
- move the following classes into package externalreader:
  - ExternalModuleResolver
  - ExternalResourceResolver
  - MessageTransportModuleResolver (renamed to ExternalModuleResolverImpl, made package-private)
  - MessageTransportResourceResolver (renamed to ExternalResourceResolverImpl, made package-private)
- replace interface ExternalModuleResolver.Spec with record ExternalModuleReaderSpec
- replace interface ExternalResourceResolver.Spec with record ExternalResourceReaderSpec
- translate between messaging.ResourceReaderSpec and ExternalResourceReaderSpec (eliminates dependency from messaging on higher layer)
- translate between messaging.ResourceResolverSpec and ExternalResourceResolverSpec (eliminates dependency from messaging on higher layer)
- add ServerMessages.ExternalReader and translate between this message component and the PklEvaluatorSettings.ExternalReader API
- add ServerMessages.Proxy and translate between this message component and the PklEvaluatorSettings.Proxy API
- change type of CreateEvaluatorRequest.allowedModules/allowedResources from List<Pattern>? to List<String>?
  - removes a lot of code
  - should not need to create a Pattern object to send a message
- deprecate method evaluatorSettings.PklEvaluatorSettings.Proxy.create()
  - only seems useful internally, inlined

Co-authored-by: Dan Chao <dan.chao@apple.com>
2025-02-20 22:38:51 -08:00
Daniel Chao
31c80e792e Ensure findOrAddAuxiliarySlot is not called during compilation (#969)
Fixes an issue that is preventing the native executable from building
2025-02-20 08:09:22 -08:00
Artem Yarmoliuk
50cfb1c962 Bump clikt to 5.0.3 (#947)
This bumps Clikt from version 3 to version 5, which, among other things, improves
the help text formatting with colors.

Also: 
* Add `--version` flag to pkldoc, pkl-codegen-java, pkl-codegen-kotlin
* Add help text to pkldoc, pkl-codegen-java, pkl-codegen-kotlin
2025-02-19 15:18:02 -08:00
Daniel Chao
643c6f5a76 Execute typechecks eagerly when within a constraint (#964)
This changes the language to check all types eagerly when within a type constraint.

This addresses two regressions in the language:

1. Type constraints are too relaxed (listing/mapping parameters may not be checked)
2. Failing type constraints hide members that were forced during execution of the constraint
2025-02-19 12:51:52 -08:00
Daniel Chao
227f0637fc Rename package ast to syntax (#968) 2025-02-19 10:57:41 -08:00
Vladimir Matveev
baa34a6dd1 Added support for an alternative current dir mode in pkldoc (#824)
Some systems have trouble with handling symlinks, which breaks the current directory links created by Pkldoc. In this PR, we add an alternative mode which creates a full copy of the latest published version contents in the current directory instead.

Co-authored-by: Dan Chao <dan.chao@apple.com>
2025-02-19 08:52:32 -08:00
Islon Scherer
2ffd201172 move handling of strings to parser (#962) 2025-02-19 17:19:48 +01:00
Daniel Chao
ee23a8c3f4 Make CliktCommands classes (#963)
Missed these three classes.

This prevents the AOT compiler from statically initializing CLI argument
default values (like working dir).
2025-02-18 08:29:59 -08:00
Daniel Chao
28b128f86f Run spotless formatting (#958)
When we updated spotless's Java and Kotlin formatter, we changed the underlying
formatting rules.
However, due to spotless ratcheting, these formatting changes don't get applied unless a file
gets touched in a commit.

To avoid future PRs introducing lines of change that aren't related to the intention of the PR,
this is a one-time format of all files.
2025-02-17 07:36:43 -08:00
Islon Scherer
d270829ed3 fix calculation of spans in parser (#957) 2025-02-15 12:11:55 +01:00
Michael Case
350b71a634 Fix incorrect glob example (#956)
Correct glob docs and use realistic file extensions.
2025-02-14 13:31:04 -08:00
Daniel Chao
28df90527b Add docs for various keywords (#955) 2025-02-14 13:30:22 -08:00
Daniel Chao
eabfcdd333 Allow -DcommitId flag when building Pkl (#954)
This is to allow building Pkl in environments that don't have access
to git.
2025-02-14 09:36:47 -08:00
Daniel Chao
1a4f9ee72e Improve handling of errors when analysis fails (#948)
Modules that cannot be loaded for one reason or another now cause a Pkl Exception,
with the offending import highlighted as part of the stack trace.
2025-02-13 14:00:48 -08:00
Daniel Chao
65cf3237b7 Add parser benchmarks (#953)
The current benchmark is not too useful now that we have a linear parser.

This changes the benchmarks to parse the standard library, and also the language snippet tests.

Co-authored-by: Islon Scherer <islonscherer@gmail.com>
2025-02-13 11:22:31 -08:00
Daniel Chao
d00d0ba79f Update dependencies (#938) 2025-02-13 10:19:24 -08:00
Josh B
f56b1bb84f Test and document supercalls using the same method/property name (#943) 2025-02-12 21:10:37 -08:00
Islon Scherer
b526902bf0 Replace ANTLR with hand-rolled parser (#917)
Co-authored-by: Kushal Pisavadia <kushi.p@gmail.com>
Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>
2025-02-12 18:11:00 +01:00
Daniel Chao
7c3f8ad261 Improve documentation about Set/Map ordering (#944)
The language reference and stdlib are both slightly incorrect;
maps and sets are ordered when iterated on, but unordered in terms of
equality.
2025-02-12 06:43:51 -08:00
Daniel Chao
7ed710c226 Make commands classes instead of objects (#946)
Making these classes caused native-image to statically initialize
them at build time, which included CLI argument default values
(like working dir).

This turns them back into classes.

Co-authored-by: Islon Scherer <islonscherer@gmail.com>
2025-02-11 06:38:19 -08:00
Josh B
ad99e4a7f7 Correctly set allowed modules/resoures when external reader scheme contain regex control characters (#941) 2025-02-07 14:03:40 -08:00
Daniel Chao
e85e888f92 [docs] Add documetation about release/evolution/roadmap (#937) 2025-02-05 11:24:41 -08:00
Daniel Chao
3b6fbdff15 Remove usages of VmFunction#apply(Object) (#936)
These call sites should use `ApplyVmFunction1Node` instead.
2025-02-05 09:18:42 -08:00
Daniel Chao
9784cd7265 Turn CLI commands into objects, self register subcommands (#935)
Usages of `RootCommand` no longer need to initialize a new instance, nor register subcommands.
2025-02-05 09:18:23 -08:00
Daniel Chao
aadcccd0fc Run a simple eval script (#928)
Execute `1 + 1` instead of eval'ing `circleci.pkl` (might cause
spurious failures due to requirement on network connection).
2025-02-04 07:21:57 -08:00
Daniel Chao
9075ca0729 Fix native gvm ci (#930)
* Update GraalVM checksum
* Fix: download JDK on macOS

Signed-off-by: Sam Gammon <sam@elide.dev>
Co-authored-by: Sam Gammon <sam@elide.dev>
2025-02-04 07:21:42 -08:00
Sam Gammon
5e12dfb200 fix: upgrade ci jobs to jdk 21 (#926)
Signed-off-by: Sam Gammon <sam@elide.dev>
2025-02-03 17:17:07 -08:00
Sam Gammon
408242a44c Upgrade GraalVM and Truffle, set up multi-JDK testing, bump development Java to 21 (#876)
This updates the GraalVM and Truffle libraries to 2024.1.2.

This also updates the build logic to compile Java sources using Java 21, due to some compile-only dependencies within GraalVM/Truffle using class file version 65. However, the produced artifact is still compatible with Java 17.

This also changes the Gradle build logic to use toolchains, and to test the Java libraries with JDK 17 and 21.

One consequence of this change is that Truffle is no longer shaded within the fat jars.

feat: support for jvm21+ toolchain
feat: support for gradle toolchains
feat: pass -PnativeArch=native to build with -march=native
test: multi-jdk testing support
test: support for jvm-test-suite plugin
test: add tasks to run jpkl eval on multiple jdks
test: make jdk exec tests respect multi-jdk flags and ranges
fix: remove mrjar classes at >jvm17 from fatjars
fix: use jdk21 to run the tests (needed for Unsafe.ensureInitialized)
fix: truffle svm dependency is required after graalvm 24.0.0
fix: warnings for gvm flag usage, renamed truffle svm macro
fix: build with --add-modules=jdk.unsupported where needed
fix: don't use gu tool for modern graalvm versions
fix: catch Throwable instead of deprecated-for-removal ThreadDeath
chore: buildinfo changes for JVM targets, toolchains
chore: enforce testing at exactly jdk21
chore: enforce build tooling at jdk21+
chore: bump graalvm/truffle libs → 24.1.2
chore: toolchains for buildSrc

Signed-off-by: Sam Gammon <sam@elide.dev>
2025-02-03 14:57:40 -08:00
Stanley Cheung
8cfd2357c6 Fix typo in tutorial part 2 (#921) 2025-01-31 07:53:22 -08:00
Sam Gammon
3fa935b390 fix: downstream native-image builds (#914)
SVM (SubstrateVM) compile configuration classes
must be included within the `cli` jar to prevent
downstream `native-image` builds from failing.

Fat JARs cannot be used with `native-image`, so
these classes can still safely be excluded here.

Fixes and closes apple/pkl#907

Signed-off-by: Sam Gammon <sam@elide.dev>
2025-01-29 20:31:05 -08:00
Kushal Pisavadia
aa8a0f18e8 Simplify inputs for javadocJar (#916)
Also, rename `dummy` to `placeholder`
2025-01-29 09:46:39 -08:00
Daniel Chao
3815a0206b Optimization: execute const object bodies and typechecks only once (#915)
If the object member is const, it only needs to be executed once, and all children in the prototype chain can use its cached value.

There is a possible other optimization here, not included in this PR: we can avoid adding these values to the child object's cachedMembers.
2025-01-29 07:19:55 -08:00
odenix
90df0662af Overhaul implementation of for-generators (#844)
Motivation:
* fix known bugs and limitations of for-generators
* improve code health by removing complex workarounds

Changes:
* simplify AstBuilder code related to for-generators
  * track for-generators via `SymbolTable.enterForGenerator()`
  * add `RestoreForBindingsNode` during initial AST construction
    instead of calling `MemberNode.replaceBody()` later on
  * simplify some unnecessarily complex code
* remove workarounds and band-aids such as:
  * `isInIterable`
  * `executeAndSetEagerly`
  * adding dummy slots in `AmendFunctionNode`
* overhaul implementation of for-generators
  * store keys and values of for-generator iterations in regular instead of auxiliary frame slots
    * set them via `TypeNode.executeAndSet()`
    * `ResolveVariableNode` no longer needs to search auxiliary slots
    * `Read(Enclosing)AuxiliarySlot` is no longer needed
  * at the start of each for-generator iteration, create a new `VirtualFrame`
    that is a copy of the current frame (arguments + slots)
    and stores the iteration key and value in additional slots.
  * execute for-generator iteration with the newly created frame
    * `childNode.execute(newFrame)`
    * Pkl objects created during the iteration will materialize this frame
  * store newly created frames in `owner.extraStorage`
    if their for-generator slots may be accessed when a generated member is executed
    * resolving variable names to for-generator variables at parse time would make this analysis more precise
  * when a generated member is executed,
	  * retrieve the corresponding frame stored in `owner.extraStorage`
	  * copy the retrieved frame's for-generator slots into slots of the current frame

Result:
* for-generators are implemented in a correct, reasonably simple, and reasonably efficient way
  * complexity is fully contained within package `generator` and `AstBuilder`
* for-generator keys and values can be accessed from all nested scopes:
  * key and value expressions of generated members
  * condition expressions of nested when-generators
  * iterable expressions of nested for-generators
* for-generator keys and values can be accessed from within objects created by the expressions listed above
* sibling for-generators can use the same key/value variable names
* parent/child for-generators can use the same key/value variable names
* fixes https://github.com/apple/pkl/issues/741
2025-01-28 14:06:42 -08:00
Kushal Pisavadia
11169d6691 Upgrade gradle to 8.12.1 (from 8.12) and fix some build warnings (#910)
Build warning fixes:

* Return `tasks.register` as `tasks.create` is deprecated
* Use property accessor `.files` instead of function `.files()`
2025-01-27 15:01:19 -08:00
Daniel Chao
5dc672731d Bump minimum Gradle version to 8.2 (#901)
The Kotlin 2.0 version upgrade made us incompatible with Gradle 8.1.

Given that it is now over 1.5 years old, this drops support for it, and
raises the minimum version to 8.2.
2025-01-27 10:04:31 -08:00
odenix
258eda8630 Update Kotlin to 2.0 (#900)
- update Kotlin from 1.7.10 to 2.0.21
  - Kotlin 1.6 dependencies in Gradle lock files are expected because kotlinc,
    which is also used by some tests, internally uses some 1.6 dependencies
    for backwards compatibility reasons.
- update kotlinx-html and kotlinx-serialization
- adapt Kotlin code where necessary
- use Kotlin stdlib Path APIs where possible
- fix IntelliJ Kotlin inspection warnings
- reformat code with `./gradlew spotlessApply`
  - ktfmt adds lots of trailing commas
- Add workaround to fix IntelliJ "unresolved reference" errors
2025-01-23 14:41:59 -08:00
Daniel Chao
cdd6d52642 Only run Gradle compatibility tests against minimum and maximum release (#898)
Currently, we run against every release version, which is taking 20
minutes to run in CI, and this will grow as Gradle creates more
releases.

This limits the amount of Gradle versions being tested against;
theoretically, only testing against the minimum version and the maximum
version should ensure that we are compatible with every version in the
range.
2025-01-22 14:08:45 -08:00
Daniel Chao
29049ac437 Import release notes for 0.27.2 (#897) 2025-01-22 09:36:48 -08:00
Daniel Chao
2a9b10097d Revert "Upgrade Kotlin to 1.7.21 (#887)" (#896)
This reverts commit 273d1219a6.
2025-01-22 08:33:06 -08:00
Daniel Chao
257bd6f699 Allow jar:nested: URIs in default security manager (#895)
Nested jars built by spring boot can possibly represent classpath
resource URIs as "jar:nested:".

This changes Pkl to by default trust them with the same level as
modulepath URIs.
2025-01-22 06:42:47 -08:00
Vic
75bd21420b Document where to find all keywords (#892) 2025-01-21 13:03:43 -08:00
Kushal Pisavadia
273d1219a6 Upgrade Kotlin to 1.7.21 (#887)
What's new: https://kotlinlang.org/docs/whatsnew1720.html

Releases
--------

- https://github.com/JetBrains/kotlin/releases/tag/v1.7.20
- https://github.com/JetBrains/kotlin/releases/tag/v1.7.21
2025-01-17 14:12:31 +00:00
Daniel Chao
ec7d7267dc Update dependencies (#883)
Most of these dependencies are test dependencies.
2025-01-15 05:39:14 -08:00
Daniel Chao
3096da1920 Update gradle to 8.12 (#884) 2025-01-15 05:38:51 -08:00
Daniel Chao
100dd0560e Support jpkl executable for Windows (#872)
This updates the script used to start the executable to support
Windows as well.

For Windows support, the executable needs to be named `jpkl.bat`.
2025-01-14 05:16:59 -08:00
Josh B
3296dd8a89 Fix NPE when handling ExternalReader specs with null arguments (#882) 2025-01-14 04:51:09 -08:00
Josh B
160e4a5636 YamlRenderer: allow all primitive scalar types as map keys (#879) 2025-01-13 16:22:52 -08:00
Josh B
267de3c789 Fix page size for Linux AArch64 native executables (#875)
Graal Native Image is assuming 4k page size here, which is a naughty assumption to make in the modern Linux-on-ARM landscape.
Two very common hardware configurations require 16k minumum page size: the Raspberry Pi 5 and Asahi Linux (running on Apple Silicon hardware).

This change forces 64k pages for Linux/AArch64 native executables to guarantee compatibility with these platforms.
DEVELOPMENT.adoc is also updated to cover the additional dependencies required for building native executables on Linux.
2025-01-07 15:55:27 +00:00
Daniel Chao
f6c74e90a8 Update license year (#871)
* Update license header file spec to use placeholder year
* Update spotless to use ratchet formatting (only format files that have changed)
2025-01-07 10:15:07 +00:00
Stefan M.
467e64f98e Make Test Report locale independent (#868)
Format numbers with `.` decimals
2025-01-02 09:29:48 -08:00
Josh Soref
d9c65d484a Fix spelling errors (#846)
Also: change checksums due to filename and content changes, and fix language snippet test output to produce correct error messages
2024-12-23 12:49:56 -08:00
Daniel Chao
a014e8d1d1 Add comment about const check (#859) 2024-12-23 11:38:33 -08:00
Daniel Chao
6fd82a5bb8 Clarify terminology on renderer converters (#860) 2024-12-20 10:36:51 -08:00
Daniel Chao
29fb99ffea Update JDK version in dev docs (#848) 2024-12-20 10:36:35 -08:00
Daniel Chao
efe1608bd6 Fix compile error (#857)
PRs https://github.com/apple/pkl/pull/789 and https://github.com/apple/pkl/pull/837 being merged caused a compile error; this fixes them.
2024-12-19 12:15:30 -08:00
Josh B
6cab47067b Fix CreateEvaluatorRequest decoding (#853)
Handle case when request specifies external reader with null arguments
2024-12-19 09:59:22 -08:00
odenix
17f431370a Fix exception handling of PklRootNode's (#837)
Motivation:
- Perform same exception handling for every implementation of PklRootNode.execute().
- Avoid code duplication.

Changes:
- Change PklRootNode.execute() to be a final method that performs exception handling
  and calls abstract method executeImpl(), which is implemented by subclasses.
- Remove executeBody() methods, which served a similar purpose but were more limited.
- Remove duplicate exception handling code.

Result:
- More reliable exception handling.
  This should fix known problems such as misclassifying stack overflows
  as internal errors and displaying errors without a stack trace.
- Less code duplication.
2024-12-19 09:58:44 -08:00
Daniel Chao
9982511513 Download JDK for windows build (#851)
Don't use the system Java on Windows builds, instead download them from Adoptium.

Also:

* Fail job if curl returns a 4xx status code
* Add java version to `GradleJob`
2024-12-19 09:23:04 -08:00
Kushal Pisavadia
6bd8e288ef Convert org.pkl.executor.Version.Identifier POJO to record class (#836) 2024-12-16 14:36:41 -08:00
odenix
01bf844a96 codegen-java: Support not annotating constructor parameters (#792)
Motivation:
Spring Boot configuration classes neither require nor benefit from annotating constructor parameters with their name.
The same is true for pkl-config-java configuration classes compiled with `-parameter`.

Changes:
- Change CLI parameter `--params-annotation` to accept a `none` value.
  This is recommended in https://clig.dev/#arguments-and-flags and is how the `-F` parameter of the `ssh` command works.
- Change `paramsAnnotation` property in Gradle plugin, CliJavaCodeGeneratorOptions, and JavaCodegenOptions as follows:
  - Change meaning of `null` from "generate org.pkl.java.config.mapper.Named annotations" to "do not generate annotations".
    This is a breaking change (only) affecting users who explicitly set the property to `null` instead of omitting it.
  - Change property default from `null` to:
    `null` if `generateSpringBootConfig` is `true` and `org.pkl.java.config.mapper.Named` otherwise
- add tests
- update docs of this and other codegen options

Result:
Generated code does not contain unnecessary annotations.
2024-12-13 14:29:18 -08:00
Islon Scherer
70aaa6322e Add release notes for 0.27.1 (#840)
Co-authored-by: Philip K.F. Hölzenspies <holzensp@gmail.com>
2024-12-06 16:24:49 +01:00
odenix
1bc473ba54 Improve lazy type checking of listings and mappings (#789)
Motivation:
- simplify implementation of lazy type checking
- fix correctness issues of lazy type checking (#785)

Changes:
- implement listing/mapping type cast via amendment (`parent`) instead of delegation (`delegate`)
- handle type checking of *computed* elements/entries in the same way as type checking of computed properties
  - ElementOrEntryNode is the equivalent of TypeCheckedPropertyNode
- remove fields VmListingOrMapping.delegate/typeNodeFrame/cachedMembers/checkedMembers
- fix #785 by executing all type casts between a member's owner and receiver
- fix #823 by storing owner and receiver directly
  instead of storing the mutable frame containing them (typeNodeFrame)
- remove overrides of VmObject methods that are no longer required
  - good for Truffle partial evaluation and JVM inlining
- revert a85a173faa except for added tests
- move `VmUtils.setOwner` and `VmUtils.setReceiver` and make them private
  - these methods aren't generally safe to use

Result:
- simpler code with greater optimization potential
  - VmListingOrMapping can now have both a type node and new members
- fewer changes to surrounding code
- smaller memory footprint
- better performance in some cases
- fixes https://github.com/apple/pkl/issues/785
- fixes https://github.com/apple/pkl/issues/823

Potential future optimizations:
- avoid lazy type checking overhead for untyped listings/mappings
- improve efficiency of forcing a typed listing/mapping
  - currently, lazy type checking will traverse the parent chain once per member,
    reducing the performance benefit of shallow-forcing
	  a listing/mapping over evaluating each member individually
- avoid creating an intermediate untyped listing/mapping in the following cases:
  - `new Listing<X> {...}`
  - amendment of `property: Listing<X>`
2024-12-06 13:41:33 +01:00
translatenix
ad06a96a8a Update Gradle to 8.11 (#800)
Changes:
- Update wrapper by running the following command:
  ./gradlew wrapper --gradle-version 8.11 --gradle-distribution-sha256-sum
  57dafb5c2622c6cc08b993c85b7c06956a2f53536432a30ead46166dbca0f1e9
- Verify wrapper JAR integrity according to:
  https://docs.gradle.org/current/userguide/gradle_wrapper.html#
  manually_verifying_the_gradle_wrapper_jar
- Replace usages of deprecated method `Project.exec` with `ExecOperations.exec`
- Convert extension function `Task.configureInstallGraalVm` to task class `InstallGraalVm`
  - a task class is the cleanest way to get hold of `ExecOperations`
- Move extension property `BuildInfo.GraalVm.downloadFile` into class `GraalVm`
- Don't apply plugin `pklGraalVm` in project `bench` (unnecessary, now causes error)
2024-11-22 11:16:04 -08:00
Islon Scherer
1abd174d77 Fix possible stack overflow in Listing/Mapping type checking (#826) 2024-11-22 09:39:52 +01:00
translatenix
45302c8a00 Switch from com.squareup.javapoet to com.palantir.javapoet (#790)
Motivation:
com.squareup.javapoet is EOL.
com.palantir.javapoet is an actively maintained fork that supports generating record classes.
2024-11-20 16:16:51 -08:00
translatenix
e6c1e1411b Update SnakeYAML Engine to 2.8 (#813)
Changes:
- update version selector and lock files
- adapt code to breaking changes
2024-11-20 15:21:12 -08:00
Artem Yarmoliuk
cc579f8fd6 Add math.atan2 (#819) 2024-11-18 14:11:19 -08:00
Daniel Chao
b93cb9b322 Exclude non file-based modules from synthesized *GatherImports task (#821)
This fixes an issue where certain modules tasks fail due to the plugin
attempting to analyze their imports, but the arguments may not actually be
Pkl modules.

For example, the pkldoc task accepts entire packages in its "sourceMoules" property.

This changes the gather imports logic to only analyze file-based modules.
This is also a performance improvement; non file-based modules are unlikely to import
files due to insufficient trust levels.

Also: fix a bug when generating pkldoc on Windows
2024-11-18 11:14:17 -08:00
translatenix
7c1604b264 Delete obsolete file pkl-certs/gradle.lockfile (#820) 2024-11-17 12:38:13 -08:00
translatenix
0c6808566f codegen-kotlin: Deprecate method toKotlinCodegenOptions without replacement (#810)
Motivation:
`CliKotlinCodeGeneratorOptions.toKotlinCodegenOptions` is an internal method that isn't useful to clients.
2024-11-14 12:21:07 -08:00
translatenix
51df2f3aa4 Convert org.pkl.core.Release into a record (#812)
Also, add doc comments to some methods.
2024-11-14 12:20:37 -08:00
Kushal Pisavadia
09bc09d058 Join concatenated String constants in test into single String (#814) 2024-11-14 08:09:25 -08:00
Kushal Pisavadia
16af6b7bcc Use text block to improve readability of test (#815) 2024-11-14 07:14:04 -08:00
Kushal Pisavadia
2a7eec592d Delete unused PclLexer.tokens file (#818) 2024-11-14 14:35:58 +01:00
Kushal Pisavadia
dda457aa8e Delete unused Resource.pcl-expected.pcf input file (#817) 2024-11-14 14:34:50 +01:00
Kushal Pisavadia
696a325511 Rename snippet tests to match content: minPklVersion (#816) 2024-11-14 14:33:46 +01:00
Kushal Pisavadia
9a27616956 Convert org.pkl.core POJOs to record classes (#808) 2024-11-13 15:54:41 -08:00
translatenix
406fa4cf40 Rename JavaCodegenOptions to JavaCodeGeneratorOptions (#801)
The new name is consistent with existing names JavaCodeGenerator and CliJavaCodeGeneratorOptions.
Backward compatibility is ensured by turning JavaCodegenOptions into a (deprecated) type alias.

Also: deprecate `CliJavaCodeGeneratorOptions.toJavaCodegenOptions()`
2024-11-13 15:43:33 -08:00
translatenix
df38011c9e codegen-java/kotlin: Fix generation of hashCode methods (#802)
codegen-java:
- use `pattern.pattern()` instead of `pattern` in hashCode method
  (consistent with equals method)

codegen-kotlin:
- use `regex.pattern` instead of `regex` in hashCode method
  (consistent with equals method)
- if a data class has a Regex property, generate not only
  an equals method but also a hashCode method
2024-11-13 15:42:45 -08:00
translatenix
b8d90eddec codegen-kotlin: Generate toString() methods consistent with data classes (#793)
Motivation:
codegen-kotlin generates a mix of data classes and regular classes.
For regular classes, toString() methods are also generated.
However, the output of generated toString() methods
differs from the output of default toString() methods of data classes.

Changes:
Generate toString() methods that produce the same output
as default toString() methods of data classes.

Also: rename KotlinCodegenOptions to KotlinCodeGeneratorOptions

The new name is consistent with existing names KotlinCodeGenerator and CliKotlinCodeGeneratorOptions.
Backward compatibility is ensured by turning KotlinCodegenOptions into a (deprecated) type alias.
2024-11-13 15:22:11 -08:00
translatenix
9faff5e551 Fix length of listings with computed index (#797)
Motivation:
The following expression evaluates to 2 instead of 1:
new Listing { "value" } { [0 + 0] = "override" }.length

Changes:
- fix length computation in EntriesLiteralNode
- improve `api/listing` tests
- make snippet test failures diffable in IntelliJ

Result:
- fixes https://github.com/apple/pkl/issues/780
- improved dev experience in IntelliJ
2024-11-13 18:29:37 +00:00
Kushal Pisavadia
3f91824dc2 Convert org.pkl.core.runtime POJOs to record classes (#807) 2024-11-13 13:09:21 +00:00
Kushal Pisavadia
dddbb27143 Convert org.pkl.core.project POJOs to record classes (#749) 2024-11-12 17:08:01 -08:00
Kushal Pisavadia
3246a0e449 Convert org.pkl.core.resource POJOs to record classes (#748) 2024-11-12 17:07:52 -08:00
translatenix
a22a8a8127 Fix Javadoc warning emitted by Gradle build (#798) 2024-11-11 11:37:14 -08:00
Kushal Pisavadia
ff60f61cbb Convert org.pkl.core.util POJOs to record classes (#750) 2024-11-11 10:00:33 -08:00
Josh B
0d199892b8 Fix a possible deadlock during external reader process close (#786)
* Fix a possible deadlock during external reader process close

* Apply spotless

---------

Co-authored-by: Philip K.F. Hölzenspies <holzensp@gmail.com>
2024-11-07 11:24:16 +00:00
Nick Muerdter
a533e53838 Fix broken link to documentation site in release notes (#784) 2024-11-05 12:56:40 -08:00
Dan Chao
44fd680e43 Start next dev iteration 2024-11-05 10:34:31 -08:00
Dan Chao
33bffbe158 Prepare 0.27.0 release 2024-11-05 10:34:31 -08:00
Daniel Chao
7eedcf1e50 Prepare 0.27.0 release notes (#756)
Co-authored-by: translatenix <119817707+translatenix@users.noreply.github.com>
Co-authored-by: Philip K.F. Hölzenspies <holzensp@gmail.com>
Co-authored-by: Islon Scherer <islonscherer@gmail.com>
2024-11-05 09:49:50 -08:00
Daniel Chao
a85a173faa Fix equals/hashCode/hasCachedValue in delegating listings/mappings (#781)
This fixes issues when a mapping/listing delegates to another mapping/listing.

The core issue is that `cachedValues` is not guaranteed to be the complete set
of the object's members; they may be stored on the delegate instead.

Therefore, it's not correct compute hash code and equality based on `cachedValues`.
Instead, it's better to use the `getCachedValue()` method, which has the correct
logic for looking up the existing cached value.
2024-11-05 09:05:36 -08:00
Daniel Chao
b402463f3c Eagerly check function arguments when called from inside iterable (#778)
This mitigates an issue where lazy mappings and listings widen an existing bug.

This is a follow-up to https://github.com/apple/pkl/pull/752.
2024-11-05 09:05:09 -08:00
translatenix
6d161ce1d4 Polish ANSI formatting and underlying code (#779)
- change line numbers from blue to faint to improve legibility on dark backgrounds
- use EnumSet throughout
- move all ANSI classes into package core.util (no need to split them over util and runtime)
- rename AnsiCodingStringBuilder to AnsiStringBuilder
2024-11-05 08:54:35 -08:00
Daniel Chao
40a08affa6 Use ANSI colors for test results; more polish (#771)
Any thrown Pkl Errors are colored in the simple test report!

Also:
* Refactor `TextFormatter` to be more generic; rename to `TextFormattingStringBuilder`
* Adjust test report slightly (no emojis, add more spacing).
* Introduce `ColorTheme` class.
* Make stack frame descriptors colored as "faint"

Also: this changes the summary so it summarizes _all_ modules, rather than a summary per module.

---------

Co-authored-by: Islon Scherer <islonscherer@gmail.com>
Co-authored-by: Philip K.F. Hölzenspies <holzensp@gmail.com>
2024-11-04 14:14:19 -08:00
Daniel Chao
4b4d81ba93 Fix semver comparison logic (#773)
Fix `isLessThan` logic between semvers
2024-11-03 20:31:04 -08:00
Josh B
9692504b5f Remove pkl.core.messaging from core APIs (#770) 2024-11-01 14:53:16 -07:00
Josh B
fa25fb46fd More external reader refinements (#766)
* org.pkl.core.Readers -> org.pkl.core.Closeables
* Remove coupling between pkl.core.module/resource and pkl.core.messaging
2024-11-01 14:05:45 -07:00
translatenix
3f38173ed5 Update commonmark and test dependencies (#767) 2024-11-01 12:48:01 -07:00
translatenix
d50179827d Update to GraalVM 23.0.6 and GraalVM for JDK 17.0.12 (#765)
GraalVM for JDK 17.0.12 is the final Critical Patch Update
made available under the GraalVM Free Terms and Conditions license.
Subsequent Critical Patch Updates require a commercial license.
2024-11-01 12:42:08 -07:00
Philip K.F. Hölzenspies
03462fefae Add color to error formatting (#746)
* Add color to error formatting

* Apply suggestions from code review

Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>

* Address reviewer comments

* Apply suggestions from code review

Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>

* Define style choices as operations on formatter (abandon semantic API)

* Adjust margin styling

* Review feedback

* Documentation nits

---------

Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>
2024-11-01 10:02:19 +00:00
Josh B
e217cfcd6f Refine external reader API (#762)
* Encapsulate message transport by removing `ExternalReaderProcess.getTransport` and adding `getModuleResolver` and `getResourceResolver` methods
* Reuse `Random` instances within `ExternalReaderProcessImpl` and module/resource resolvers
* Externalize all `ExternalReaderProcessException` messages
* Add some missing doc comments to `ModuleKeyFactories` and `ResourceReaders` methods for external readers
* Move org.pkl.core.util.Readers to org.pkl.core.Readers
2024-10-31 16:51:25 -07:00
Daniel Chao
66d751f093 Eagerly check listing/mapping in iterables (#752)
There is currently a bug around resolving variables within the iterable of a for
generator or spread syntax (https://github.com/apple/pkl/issues/741)

Normally, mappings/listings are type-checked lazily. However, this results in the said
bug getting widened, for any object members declared in the iterable.

As a workaround for now, prevent the bug from being any worse by ensuring that these
object members are eagerly typechecked.
2024-10-31 14:22:24 -07:00
translatenix
1be1fe4863 Use VmObjectBuilder in Listing.distinct(By) implementations (#760) 2024-10-31 13:28:04 -07:00
translatenix
cc72f9d160 Polish external reader API/implementation (#759)
- keep implementation classes internal to their packages
- make classes final if possible
- make namespace classes non-instantiable
- throw IllegalStateException instead of ExternalReaderProcessException for use after close
  - common convention already used by HttpClient etc.
  - programming errors should be signaled with unchecked exceptions
- use private instead of public lock object
- polish Javadoc
- delete commented out code
- don't use star import for a single class
2024-10-31 13:12:19 -07:00
Philip K.F. Hölzenspies
a03827951c Add methods from List/Map to Listing/Mapping (#683)
* Add `values` to `Mapping`

* Add `entries` to `Mapping`

* Add `containsValue` to `Mapping`

* Add `every` to `Mapping`

* Add `any` to `Mapping`

* Add `toDynamic` to `Mapping`

* Add `lastIndex` to `Listing`

* Add `getOrNull` to `Listing`

* Add `first` to `Listing`

* Add `firstOrNull` to `Listing`

* Add `last` to `Listing`

* Add `lastOrNull` to `Listing`

* Add `single` to `Listing`

* Add `singleOrNull` to `Listing`

* Add `contains` to `Listing`

* Add `any` to `Listing`

* Add `every` to `Listing`

* Fixup `any` to `Listing`

* Revert "Add `toDynamic` to `Mapping`"

This reverts commit 5551974ecd8110aa2eb8f546e992c32d3181df9b.

* Revert "Add `values` to `Mapping`"

This reverts commit 6fc78796

* Revert "Add `entries` to `Mapping`"

This reverts commit a7e8dfc4

* Annotate new members with `Since` 0.27

* Fix documentation in `base.pkl`

* Add location information to empty/single checks in `Listing` operations

* Remove additional variable for laziness preservation

* Apply spotless

* Apply suggestions from code review

Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>

---------

Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>
2024-10-31 14:54:27 +00:00
Stefan M.
71db4d0fae Replace code with italic (#753) 2024-10-30 17:15:04 +00:00
Josh B
dd16f7469e pkl-executor: fix loading projects and fix incorrectly thrown PklException
* Load `PklProject` using the same security settings and env vars passed provided via ExecutorSPIOptions
* Handle thrown `PklException` from loading `PklProject` and throw `ExecutorSPIException`
* Handle thrown `PklException` of older Pkl distributions, converting them into `ExecutorSpiException`
2024-10-29 23:29:19 -07:00
Daniel Chao
acd2222534 Polish test result running and reporting (#738)
Changes:
* Move class `TestResults` to package `org.pkl.core`, because it is a public class (it's the result of `Evaluator#evaluateTest`)
* Change examples to treat individual examples as assertions in the same test. Previously, they were considered different tests with an incrementing number. This better aligns with how facts are treated.
* Change `TestResults` to be a record, and introduce builders.
* Remove "module" test result section (it is not really a section).
* Add javadoc to `TestResults`
* Formatting fix: prefix ✍️ emoji just like we do the  and  emojis 
* Consider writing examples as failures, not successes. `pkl test` will exit with code 10 if the only failing tests are due to writing examples.
2024-10-28 21:05:13 -07:00
Josh B
666f8c3939 Implement SPICE-0009 External Readers (#660)
This adds a new feature, which allows Pkl to read resources and modules from external processes.

Follows the design laid out in SPICE-0009.

Also, this moves most of the messaging API into pkl-core
2024-10-28 18:22:14 -07:00
Daniel Chao
466ae6fd4c Exclude non-ascii files from windows native snippet tests (#739)
There is an existing bug that is preventing the CLI from loading
these files.
2024-10-26 07:56:00 -07:00
translatenix
08be6be059 codegen-java/kotlin: Support Spring Boot 3.x instead of 2.x (#729)
Motivation:
In Spring Boot 3.0, the annotation type `org.springframework.boot.context.properties.ConstructorBinding`
was deprecated in favor of `org.springframework.boot.context.properties.bind.ConstructorBinding`.
In 3.2, the old annotation type was removed.
As of 3.0, a `@ConstructorBinding` annotation is no longer required/recommended for configuration classes with a single public constructor.

Changes:
Remove generation of `@ConstructorBinding` annotations in codegen-java and codegen-kotlin.

Result:
- Generated code is compatible with Spring Boot 3.x.
  (Verified with locally updated pkl-spring.)
- Generated code is no longer compatible with Spring Boot 2.x.
  To use Pkl 0.27 and later with Spring Boot 2.x, use Pkl 0.26's code generator.
- Fixes #139.
2024-10-25 14:08:20 -07:00
translatenix
8fa3acf32f codegen-kotlin: Support Java serialization of module classes (#721)
Motivation:
- Java serialization makes as much sense for module classes as it does for regular classes.
- Offer same Java serialization support as codegen-java.

Changes:
- Move generation of `appendProperty` method and serialization code
  into new method `generateCompanionRelatedCode`.
- Improve/fix generation of serialization code.

Result:
Java serialization is also supported for module classes.
2024-10-24 22:11:35 -07:00
Islon Scherer
8b0118fec5 Store PklProject annotations in the project metadata (#708)
Write annotations to project metadata, and provide them to pkl-doc\

The following annotations have meaning for pkl-doc:
* `@Unlisted`: hide package from documentation site
* `@Deprecated`: add deprecated information
2024-10-24 17:21:58 -07:00
Islon Scherer
93cc3253eb Report error on circular local dependencies (#731)
If a stack overflow is found during project evaluation, present any
circular imports found in the dependency graph.
2024-10-24 16:45:18 -07:00
translatenix
1ceb489d78 Fix lazy type checking of UInt types (#740)
For example, Listing<UInt16> is equivalent to Listing<UInt16>, but not to Listing<UInt32>.
2024-10-24 16:19:26 -07:00
Josh B
4b6bc7bb7c Produce more helpful output when module output is overwritten (#716)
Fix a bug where overwriting `output` causes a PklBugException.

This now produces a more helpful message pointing to the actual problem.

Co-authored-by: translatenix <119817707+translatenix@users.noreply.github.com>
2024-10-24 09:41:59 -07:00
translatenix
cbbcca0d84 codegen-java: Make stateless classes instantiable (#734)
Motivation:
Currently, the condition for making a generated Java class instantiable is "class is neither abstract nor stateless".
(An instantiable class receives a public constructor and equals/hashCode/toString/with methods.)
This is inconsistent with Pkl and codegen-kotlin, both of which support instantiation of stateless classes.

Changes:
Widen condition for making a class instantiable to "class is neither abstract nor a stateless final module class".
This is consistent with codegen-kotlin, which generates object declarations (only) for stateless final module classes.

Result:
Stateless classes are instantiable in Pkl, codegen-java, and codegen-kotlin.
2024-10-24 09:29:08 -07:00
Daniel Chao
22c9a6c9f4 Exclude thrown ascii filename error from native tests (#737)
The URI encoding is not predictable here.
2024-10-24 08:20:56 -07:00
Josh B
069a5d1adc Fix test failures on main (#735) 2024-10-24 11:53:39 +01:00
Javier Maestro
86d870ba09 Improve testing with stats and errors per test section (#498)
* Emojis are moves to the left to be aligned
* A summary line is added with test counts
* Facts and Examples are grouped under their own section
2024-10-23 23:00:35 -07:00
translatenix
2040f14b07 codegen-java: Change condition for generating equals/hashCode/toString/with/Serializable (#710)
Motivation:
- Currently, the condition for generating equals/hashCode/toString methods is "generated class declares properties".
  As a result, classes that don't declare properties inherit these methods from their generated superclasses.
  However, generated `equals` and `toString` methods aren't designed to be inherited
  and will either fail or produce wrong results when called for a subclass.
- Currently, the condition for generating `with` methods is "class is not abstract".
  However, it isn't useful to generate `with` methods for non-instantiable non-abstract classes.
- Currently, the condition for making classes serializable is "class is not a module class".
  However, it isn't useful to make non-instantiable non-module classes serializable,
  and it is useful to make instantiable module classes serializable.

Changes:
- Change condition for generating equals/hashCode/toString/with/Serializable to "class is instantiable".
  This is a breaking change.
  (A generated class is instantiable, i.e., declares a public constructor,
  if it is neither abstract nor stateless. This behavior remains unchanged for now.)
- Overhaul JavaCodeGeneratorTest
  - introduce classes JavaSourceCode and JavaSourceCodeAssert
  - change assertions to use JavaSourceCodeAssert via `assertThat(javaCode)`
  - use parameterized test instead of loop
  - use explicit trimIndent() and trimMargin() for multiline string literals
    - IntelliJ editor desperately wants to insert trimIndent()
    - can potentially be exploited by kotlinc and ktfmt

Result:
- Fixes all motivating issues.
- Fixes #706.
2024-10-23 21:59:15 -07:00
translatenix
730257861f codegen-kotlin: Don't generate equals/hashCode/toString/copy/:Serializable for abstract classes (#714)
* codegen-kotlin: Don't generate equals/hashCode/toString/copy/:Serializable for abstract classes

* Polish KotlinCodeGeneratorTest

- use `assertContains()` instead of `assertThat().contains()`
- remove redundant `trimIndent()` and `trimMargin()` calls
- rename `javaCode` to `kotlinCode`

* Overhaul KotlinCodeGeneratorTest

- introduce classes KotlinSourceCode and KotlinSourceCodeAssert
- change assertions to use KotlinSourceCodeAssert via `assertThat(kotlinCode)`
- use explicit trimIndent() and trimMargin() for multiline string literals
  - IntelliJ editor desperately wants to insert trimIndent()
  - can be used by kotlinc and ktfmt
- format code in the exact way it falls out of the IntelliJ editor
  (successfully destroyed by ktfmt)
2024-10-23 21:31:08 -07:00
Josh B
f9fe226eba Fix handling of file: module URIs with non-ASCII characters (#696)
Addresses an issue where Pkl cannot evaluate files with non-ASCII characters.
2024-10-23 20:52:40 -07:00
Daniel Chao
5a654e453c Fix formatting issues (#733) 2024-10-23 20:49:16 -07:00
Daniel Chao
9d10832ffc Fix typecheck error on Listing/Mapping (#725)
The addresses the following case:

    local l1: Listing<String> = new { 1 }
    l2: Listing<Int> = (l1) { 2 }

The member in `l1` should be checked against its owner; to check against `Listing<String>`.
2024-10-23 14:38:30 -07:00
Daniel Chao
ce25cb8ef0 Add analyze imports libs (SPICE-0001) (#695)
This adds a new feature to build a dependency graph of Pkl programs, following the SPICE outlined in https://github.com/apple/pkl-evolution/pull/2.

It adds:
* CLI command `pkl analyze imports`
* Java API `org.pkl.core.Analyzer`
* Pkl stdlib module `pkl:analyze`
* pkl-gradle extension `analyze`

In addition, it also changes the Gradle plugin such that `transitiveModules` is by default computed from the import graph.
2024-10-23 14:36:57 -07:00
Philip K.F. Hölzenspies
eb3891b21f Change license header from doc- to block-comment (#730)
* Change license header from doc to block comment

* Apply fixed license header throughout
2024-10-23 16:02:42 +01:00
Philip K.F. Hölzenspies
0aa4819cea Add version of resolved Pkl distribution to ExecutorException (#719)
* Add version of resolved Pkl distribution to `ExecutorException`

* Review comments

Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>

---------

Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>
2024-10-23 10:51:53 +01:00
Kushal Pisavadia
a7cc098925 Remove isMappingDefault on VmNull (#724)
This method is unused.
2024-10-22 10:41:31 -07:00
Daniel Chao
0ee3d37524 Add support for const object members (#678)
This adds support for adding the `const` modifier to object members.

Such object members are also required to have the `local` modifier applied.

This follows SPICE-0011.
2024-10-21 22:00:12 -07:00
translatenix
5057bb5b17 Fix build performance issues of spotless tasks (#722)
Using more efficient glob expressions and removing `targetExclude()` greatly speeds up performance on some OSes.
2024-10-21 17:23:40 -07:00
translatenix
9abf1de7de List Pkl GitHub repositories in README (#715) 2024-10-21 17:22:29 -07:00
translatenix
84f4ec863c codegen-kotlin: Fix generation of copy() methods (#705)
- don't generate copy methods for abstract classes
- precisely determine if copy method needs override modifier (tricky)

Fixes #569
2024-10-19 20:32:21 -07:00
translatenix
d271b62543 Update dependencies (#689)
- Update dependencies by deleting lock files and regenerating them with `gw updateDependencyLocks`.
  Deleting lock files avoids strange `some.library:some.older.version=default` entries.
  Most updated dependencies are test dependencies.
- Handle breaking changes in library commonmark.
- Fix test to close PackageServer exactly once.
  This problem surfaced because JUnit 5.11 changed override rules for lifecycle methods,
  resulting in too many instead of too few close() calls.
- Bump msgpack version
- Bump clikt version
- Bump Gradle plugin versions
2024-10-17 09:12:07 -07:00
Josh B
62c796a257 Fix double unary minus (#697)
Fix an issue where doubly unary minus (e.g. `--1`) on int/float literals are incorrectly
parsed as single unary minus.
2024-10-17 07:30:00 -07:00
Jens Teglhus Møller
9b5c5a5c98 Fix error in spread documentation (#704) 2024-10-17 07:16:53 -07:00
Daniel Chao
2add291375 Fix formatting of let expressions (#702) 2024-10-17 07:02:24 -07:00
Daniel Chao
7ac51f1f88 Fix invalid syntax in doc comments of pkl:reflect members (#703) 2024-10-17 07:02:10 -07:00
translatenix
1022cf3ff3 Replace some usages of java.lang.String.replaceAll with String.replace (#701)
Both methods replace all occurrences.
The difference is that String.replaceAll interprets its first argument as a regex.
2024-10-16 15:00:45 -07:00
Philip K.F. Hölzenspies
421711be10 Improve let-expression examples (#680) (#699)
Because I did not understand what a `Let Expression` should be and the example code was more confusing as explanatory, I changed the format of the examples a little bit and changed the result.

- It should be clear that the example is just one code-line
- I tried out the example (`pkl eval...`) and get a little bit different result

Co-authored-by: ManuW <ManuW@users.noreply.github.com>
2024-10-16 13:10:48 +01:00
translatenix
475f29c896 Set lower limit for glob pattern resolution in test mode (#693)
Motivation:
Speed up the test that verifies enforcement of the limit for glob pattern resolution (invalidGlobImport6.pkl).

Changes:
- Set a lower limit if test mode is enabled.
- Change static field to static method to prevent compile-time evaluation by native-image.
2024-10-15 22:20:25 -07:00
translatenix
d00c466843 Fix dangling Javadoc reference (#687) 2024-10-15 08:26:35 -07:00
translatenix
7f26592360 Use case-insensitive comparison for module URI schemes (#688)
Previously, some factories used case-sensitive comparison, for no apparent reason.
2024-10-15 08:26:23 -07:00
translatenix
4854027a1a Update Gradle to 8.10.2 (#684)
Verify wrapper JAR according to:
https://docs.gradle.org/current/userguide/gradle_wrapper.html#wrapper_checksum_verification
2024-10-14 22:53:26 -07:00
translatenix
2961cdad19 Update Windows and Mac development instructions (#685) 2024-10-14 22:52:59 -07:00
translatenix
b76ff0f858 Don't run native Windows tests during pkl-core:test (#686) 2024-10-14 22:51:28 -07:00
translatenix
bc9d526b7a Update DEVELOPMENT.adoc (#682) 2024-10-14 11:00:16 +02:00
Daniel Chao
3600582908 Add .vscode and .pkl-lsp to gitignore (#677) 2024-10-11 07:59:35 -07:00
Josh B
1e63c48ce4 Add String.splitLimit API (#666)
* Add String.splitLimit API

* Update stdlib/base.pkl

Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>

---------

Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>
2024-10-07 15:28:19 +01:00
Max Rydahl Andersen
9e7e42eb53 add jbang catalog (#655) 2024-10-07 13:13:38 +02:00
Josh B
b072794d0d Handle null contents gracefully in message passing API (#657)
In messages "Read Resource Response" and "Read Module Response", if `contents` and `error` are both null, default to an empty byte array/string.

This resolves one of the issues reported in #656
2024-10-01 12:54:06 -07:00
Philip K.F. Hölzenspies
cc1e432a30 Add PklProject.deps.json file with newline for POSIX compliance (#664)
* Add Project.deps.json file with newline for POSIX compliance

* Fix test cases
2024-10-01 20:00:46 +01:00
Daniel Chao
47f2143e0d Fix PklBugException when reading local package assets (#642) 2024-09-10 05:51:34 -07:00
Daniel Chao
7868d9d9c8 Typecheck Mapping/Listing members lazily (#628)
This changes how the language performs typechecks for mappings and
listings.

Currently, Pkl will shallow-force any Mapping and Listing to check it
the type parameter (e.g. Listing<Person> means each element is checked
to be an instance of Person).

This changes the language to check each member's type when the member
is accessed.

This also adjust test runner to handle thrown errors from within tests.

With the change to make mapping/listing typechecks lazy, we can now
correctly handle thrown errors from within a single test case.

This adjusts the test runner to consider any thrown errors as a failure
for that specific test case.
2024-09-06 15:05:23 -07:00
Josh B
7001a42149 [docs] Add documentation for new keyword (#624) 2024-08-29 15:25:14 -07:00
Philip K.F. Hölzenspies
a8f24c9f13 Fix parsing of external property values containing = (#631) 2024-08-20 13:28:13 +01:00
Josh B
e5b7e046d9 [docs] Improve searchability of "Methods" section (#625) 2024-08-19 15:54:46 -07:00
LamTrinh.Dev
ef0433a9ba Correct the link for ANTLR 4 Documentation (#623) 2024-08-15 20:15:26 -07:00
Josh B
a9c4963a4a [docs] Document the class-as-a-function pattern (#614) 2024-08-15 17:06:56 -07:00
Philip K.F. Hölzenspies
e21db76efe Remove const from reserved keywords (remnant) (#626) 2024-08-14 14:48:49 +01:00
Josh B
bbdc45656c [docs] Document hidden equality/hashing behavior (#618)
* [docs] Document `hidden` equality/hashing behavior

* Update docs/modules/language-reference/pages/index.adoc

---------

Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>
2024-08-13 09:56:15 +02:00
Josh B
c445770261 [docs] Add mention of "optional" to nullably types section (#613) 2024-08-07 12:18:50 -07:00
Daniel Chao
b1c2015321 Cherry pick 0.26.3 release notes (#615) 2024-08-06 12:08:44 -07:00
Daniel Chao
7c4904429f Fix: make Gradle tests compatible with Gradle 8.1 (#610)
The tests were using assignment expressions, a Kotlin compiler feature
only available in Gradle 8.2 and onwards.
2024-08-06 07:55:13 -07:00
Daniel Chao
d5e86ed077 Fix: globbing--read extra storage from owner instead of receiver (#607)
This fixes an issue where a PklBugException is thrown when a globbed
read/import is amended.
2024-08-05 10:27:50 -07:00
Daniel Chao
604b042d1b Make EvalTask track resolved output paths and fix file() notation on Gradle on Windows (#403)
* Add `getEffectiveOutputFiles` and `getEffectiveOutputDirs` to `EvalTask`, and mark them as output files/dirs so they are tracked by Gradle. This enables implicit dependency tracking between two tasks.
* Fix usage of `file()` notation in Gradle scripts when on Windows.
2024-07-25 17:41:03 -07:00
Islon Scherer
e3133f604b Fix property parsing bug in the cli (#596) 2024-07-25 09:27:38 +02:00
XIAO YU
bfc2d7abbf refactor: Simplify regex pattern for code block matching (#592) 2024-07-24 15:13:49 +01:00
XIAO YU
0704b8cd83 Remove redundant suppression (#594) 2024-07-22 17:14:54 -07:00
Daniel Chao
e81a47a038 Import release notes for 0.26.2 (#587) 2024-07-18 09:39:13 -07:00
Daniel Chao
176ede0002 Fix race condition when concurrently downloading packages (#584)
This fixes a possible race condition where multiple processes download
the same package into the same temp dir.
2024-07-18 09:11:25 -07:00
Islon Scherer
24cc95abcc Support _ in String[toInt|toIntOrNull|toFloat|toFloatOrNull] (#580)
The logic is the same as the Pkl parser
2024-07-16 19:24:59 +02:00
Taichi Ishitani
b5e011dae1 Allow to toInt() to parse a string including "__" (#578)
Fix the issue where String#toInt() cannot parse a Int string
including sequence of "_" like "1_2__3___".
2024-07-15 10:39:17 +02:00
Thomas Purchas
cdf548cad0 Add CSS to make top doc box have a fade, rather than hard cutoff (#570)
The current hard cutoff in the docs often results in people not
realising that the doc box can be expanded, and often resulting in
confusion because the most helpful examples are often in the module doc
box.

This change uses some simple CSS tweaks to replace the hard cut-off with
a visualfade, so it's obvious that there's content hidden out of view.
Doing this required removing the CSS transition, as it hard to correctly
transition the height property of CSS element of unknown target height.
But the improved discoverablility of the doc content seems like a
worthwhile tradeoff.
2024-07-08 15:12:24 +01:00
Philip K.F. Hölzenspies
5cc2ea2d00 Revert error coloring (for development on dedicated branch) (#565) 2024-07-03 17:25:06 +01:00
Dan Chao
527d236ba4 Add Git ignore-revs file 2024-07-01 09:24:04 -07:00
Dan Chao
8c1c10528f Run spotless apply 2024-07-01 09:24:04 -07:00
Dan Chao
7a9b571f6e Use spotless to format remaining Kotlin files
Also: fix issue where some commented out Kotlin files are invalid.
2024-07-01 09:24:04 -07:00
Thomas Purchas
3659ad8b7a Add test for colour outputs
Test two error conditions that cover all current colour outputs.
2024-07-01 10:13:16 +01:00
Thomas Purchas
0d7b95d3ff Add colours to Pkl errors in Cli output
To make error messages from Pkl eval easier to read, this change uses
the Jansi library to colour the output, making it quicker and easier to
scan error messages and understand what's happened.

The Jansi library also detects if the CLI output is a terminal capable
of handling colours, and will automatically strip out escape codes if
the output won't support them (e.g. piping the output somewhere else).
2024-07-01 10:13:16 +01:00
Daniel Chao
49aaf288cc Cherry-pick release notes for 0.26.1 (#557) 2024-06-28 10:23:24 -07:00
Daniel Chao
51d7265ec6 Do not enable TLS certificate revocation checks by default (#553)
This addresses an issue where network requests may fail if cert revocation checks
error, which may occur due to availability issues, or due to lack of internet access.

Revocation checking can still be enabled by setting JVM property com.sun.net.ssl.checkRevocation if on the JVM.

Also:
* Load built-in certs from resources, and move them to pkl-commons-cli
* Fix an issue where HttpInitException is not caught when loading a module
2024-06-28 08:57:46 -07:00
Daniel Chao
420336dc78 Only run Gradle compatibility tests against releases in CI (#554)
This fixes our CI tests on main. It mitigates an issue where the current RC is borked right now.
2024-06-28 07:57:27 -07:00
Daniel Chao
70e77347f3 Use compatible architecture in native executables (#551)
Use the most compatible architecture; for example, x86-64 instead of
x86-64-v3.
2024-06-27 07:39:17 -07:00
Philip K.F. Hölzenspies
3b786878fd Pass HOMEBREW_* environment variables on through native_image 2024-06-26 16:31:31 +01:00
Philip K.F. Hölzenspies
64bfcfdc4f Resolve project dirs from working dir by default 2024-06-25 13:13:48 +01:00
Daniel Chao
5c950d2e73 docs: add contributor for 0.26 release (#546)
Add a contributor name who was missing from acknowledgements.
2024-06-24 07:47:26 -07:00
Philip K.F. Hölzenspies
0ef22a73fb Start next dev iteration 2024-06-17 19:53:30 +01:00
Philip K.F. Hölzenspies
4a27ac5bda Prepare 0.26.0 release 2024-06-17 19:53:30 +01:00
3374 changed files with 205961 additions and 23329 deletions

View File

@@ -1,166 +0,0 @@
//===----------------------------------------------------------------------===//
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
// 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"
import "jobs/BuildNativeJob.pkl"
import "jobs/GradleCheckJob.pkl"
import "jobs/DeployJob.pkl"
import "jobs/SimpleGradleJob.pkl"
local prbJobs: Listing<String> = gradleCheckJobs.keys.toListing()
local buildAndTestJobs = (prbJobs) {
"bench"
"gradle-compatibility"
...buildNativeJobs.keys.filter((it) -> it.endsWith("snapshot"))
}
local releaseJobs = (prbJobs) {
"bench"
"gradle-compatibility"
...buildNativeJobs.keys.filter((it) -> it.endsWith("release"))
}
prb {
jobs = prbJobs
}
main {
jobs {
...buildAndTestJobs
new {
["deploy-snapshot"] {
requires = buildAndTestJobs
context = "pkl-maven-release"
}
}
}
}
release {
jobs {
...releaseJobs
// do GitHub release first because we can overwrite the tag.
// publishing to Maven Central is final.
new {
["github-release"] {
requires = releaseJobs
context = "pkl-github-release"
}
}
new {
["deploy-release"] {
requires { "github-release" }
context = "pkl-maven-release"
}
}
}
}
releaseBranch {
jobs = releaseJobs
}
triggerDocsBuild = "both"
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"
}
}
}
["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"
}
}
}
local gradleCheckJobs: Mapping<String, GradleCheckJob> = new {
["gradle-check-jdk17"] {
javaVersion = "17.0"
isRelease = false
}
["gradle-check-jdk21"] {
javaVersion = "21.0"
isRelease = false
}
["gradle-check-jdk17-windows"] {
javaVersion = "17.0"
isRelease = false
os = "windows"
}
}
jobs {
for (jobName, job in buildNativeJobs) {
[jobName] = job.job
}
for (jobName, job in gradleCheckJobs) {
[jobName] = job.job
}
["bench"] = new SimpleGradleJob { command = "bench:jmh" }.job
["gradle-compatibility"] = new SimpleGradleJob {
name = "gradle compatibility"
command = #"""
:pkl-gradle:build \
:pkl-gradle:compatibilityTestReleases \
:pkl-gradle:compatibilityTestCandidate
"""#
}.job
["deploy-snapshot"] = new DeployJob { command = "publishToSonatype" }.job
["deploy-release"] = new DeployJob {
isRelease = true
command = "publishToSonatype closeAndReleaseSonatypeStagingRepository"
}.job
["github-release"] {
docker {
new { image = "maniator/gh:v2.40.1" }
}
steps {
new AttachWorkspaceStep { at = "." }
new RunStep {
name = "Publish release on GitHub"
command = #"""
# exclude build_artifacts.txt from publish
rm -f pkl-cli/build/executable/*.build_artifacts.txt
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/*
"""#
}
}
}
}

View File

@@ -1,878 +0,0 @@
# Generated from CircleCI.pkl. DO NOT EDIT.
version: '2.1'
orbs:
pr-approval: apple/pr-approval@0.1.0
jobs:
pkl-cli-macOS-amd64-release:
steps:
- checkout
- run:
command: /usr/sbin/softwareupdate --install-rosetta --agree-to-license
name: Installing Rosetta 2
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DreleaseBuild=true pkl-cli:macExecutableAmd64 pkl-core:testMacExecutableAmd64 pkl-server:testMacExecutableAmd64
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
resource_class: macos.m1.large.gen1
macos:
xcode: 15.3.0
pkl-cli-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 -L \
https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/OpenJDK17U-jdk_x64_linux_hotspot_17.0.9_9.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 -L 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 -L 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 -DreleaseBuild=true pkl-cli:linuxExecutableAmd64 pkl-core:testLinuxExecutableAmd64 pkl-server:testLinuxExecutableAmd64
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/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-cli-macOS-aarch64-release:
steps:
- checkout
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DreleaseBuild=true pkl-cli:macExecutableAarch64 pkl-core:testMacExecutableAarch64 pkl-server:testMacExecutableAarch64
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
resource_class: macos.m1.large.gen1
macos:
xcode: 15.3.0
pkl-cli-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 -L \
https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/OpenJDK17U-jdk_aarch64_linux_hotspot_17.0.9_9.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 -L 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 -DreleaseBuild=true pkl-cli:linuxExecutableAarch64 pkl-core:testLinuxExecutableAarch64 pkl-server:testLinuxExecutableAarch64
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/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-cli-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 -L \
https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/OpenJDK17U-jdk_x64_linux_hotspot_17.0.9_9.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 -L 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 -L 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 -DreleaseBuild=true pkl-cli:alpineExecutableAmd64 pkl-core:testAlpineExecutableAmd64 pkl-server:testAlpineExecutableAmd64
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/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-cli-windows-amd64-release:
steps:
- checkout
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DreleaseBuild=true pkl-cli:windowsExecutableAmd64 pkl-core:testWindowsExecutableAmd64 pkl-server:testWindowsExecutableAmd64
name: gradle buildNative
shell: bash.exe
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
resource_class: windows.large
machine:
image: windows-server-2022-gui:current
pkl-cli-macOS-amd64-snapshot:
steps:
- checkout
- run:
command: /usr/sbin/softwareupdate --install-rosetta --agree-to-license
name: Installing Rosetta 2
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results pkl-cli:macExecutableAmd64 pkl-core:testMacExecutableAmd64 pkl-server:testMacExecutableAmd64
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
resource_class: macos.m1.large.gen1
macos:
xcode: 15.3.0
pkl-cli-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 -L \
https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/OpenJDK17U-jdk_x64_linux_hotspot_17.0.9_9.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 -L 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 -L 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 pkl-cli:linuxExecutableAmd64 pkl-core:testLinuxExecutableAmd64 pkl-server:testLinuxExecutableAmd64
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/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-cli-macOS-aarch64-snapshot:
steps:
- checkout
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results pkl-cli:macExecutableAarch64 pkl-core:testMacExecutableAarch64 pkl-server:testMacExecutableAarch64
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
resource_class: macos.m1.large.gen1
macos:
xcode: 15.3.0
pkl-cli-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 -L \
https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/OpenJDK17U-jdk_aarch64_linux_hotspot_17.0.9_9.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 -L 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 pkl-cli:linuxExecutableAarch64 pkl-core:testLinuxExecutableAarch64 pkl-server:testLinuxExecutableAarch64
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/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-cli-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 -L \
https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/OpenJDK17U-jdk_x64_linux_hotspot_17.0.9_9.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 -L 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 -L 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 pkl-cli:alpineExecutableAmd64 pkl-core:testAlpineExecutableAmd64 pkl-server:testAlpineExecutableAmd64
name: gradle buildNative
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/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-cli-windows-amd64-snapshot:
steps:
- checkout
- run:
command: |-
export PATH=~/staticdeps/bin:$PATH
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results pkl-cli:windowsExecutableAmd64 pkl-core:testWindowsExecutableAmd64 pkl-server:testWindowsExecutableAmd64
name: gradle buildNative
shell: bash.exe
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
resource_class: windows.large
machine:
image: windows-server-2022-gui:current
gradle-check-jdk17:
steps:
- checkout
- run:
command: ./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results check
name: gradle check
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
docker:
- image: cimg/openjdk:17.0
gradle-check-jdk21:
steps:
- checkout
- run:
command: ./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results check
name: gradle check
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
docker:
- image: cimg/openjdk:21.0
gradle-check-jdk17-windows:
steps:
- checkout
- run:
command: ./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results check
name: gradle check
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
resource_class: windows.large
machine:
image: windows-server-2022-gui:current
bench:
steps:
- checkout
- run:
command: ./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results bench:jmh
name: bench:jmh
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
docker:
- image: cimg/openjdk:17.0
gradle-compatibility:
steps:
- checkout
- run:
command: |-
./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results :pkl-gradle:build \
:pkl-gradle:compatibilityTestReleases \
:pkl-gradle:compatibilityTestCandidate
name: gradle compatibility
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
docker:
- image: cimg/openjdk:17.0
deploy-snapshot:
steps:
- checkout
- attach_workspace:
at: '.'
- run:
command: ./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results publishToSonatype
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
docker:
- image: cimg/openjdk:17.0
deploy-release:
steps:
- checkout
- attach_workspace:
at: '.'
- run:
command: ./gradlew --info --stacktrace -DtestReportsDir=${HOME}/test-results -DreleaseBuild=true publishToSonatype closeAndReleaseSonatypeStagingRepository
- persist_to_workspace:
root: '.'
paths:
- pkl-cli/build/executable/
- store_test_results:
path: ~/test-results
environment:
LANG: en_US.UTF-8
docker:
- image: cimg/openjdk:17.0
github-release:
steps:
- attach_workspace:
at: '.'
- run:
command: |-
# exclude build_artifacts.txt from publish
rm -f pkl-cli/build/executable/*.build_artifacts.txt
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/*
name: Publish release on GitHub
docker:
- image: maniator/gh:v2.40.1
trigger-docsite-build:
steps:
- run:
command: |-
curl --location \
--request POST \
--header "Content-Type: application/json" \
-u "${CIRCLE_TOKEN}:" \
--data '{ "branch": "main" }' \
"https://circleci.com/api/v2/project/github/apple/pkl-lang.org/pipeline"
name: Triggering docsite build
docker:
- image: cimg/base:current
trigger-package-docs-build:
steps:
- run:
command: |-
curl --location \
--request POST \
--header "Content-Type: application/json" \
-u "${CIRCLE_TOKEN}:" \
--data '{ "branch": "main" }' \
"https://circleci.com/api/v2/project/github/apple/pkl-package-docs/pipeline"
name: Triggering docsite build
docker:
- image: cimg/base:current
workflows:
prb:
jobs:
- hold:
type: approval
- pr-approval/authenticate:
context: pkl-pr-approval
- gradle-check-jdk17:
requires:
- hold
- gradle-check-jdk21:
requires:
- hold
- gradle-check-jdk17-windows:
requires:
- hold
when:
matches:
value: << pipeline.git.branch >>
pattern: ^pull/\d+(/head)?$
main:
jobs:
- gradle-check-jdk17
- gradle-check-jdk21
- gradle-check-jdk17-windows
- bench
- gradle-compatibility
- pkl-cli-macOS-amd64-snapshot
- pkl-cli-linux-amd64-snapshot
- pkl-cli-macOS-aarch64-snapshot
- pkl-cli-linux-aarch64-snapshot
- pkl-cli-linux-alpine-amd64-snapshot
- pkl-cli-windows-amd64-snapshot
- deploy-snapshot:
requires:
- gradle-check-jdk17
- gradle-check-jdk21
- gradle-check-jdk17-windows
- bench
- gradle-compatibility
- pkl-cli-macOS-amd64-snapshot
- pkl-cli-linux-amd64-snapshot
- pkl-cli-macOS-aarch64-snapshot
- pkl-cli-linux-aarch64-snapshot
- pkl-cli-linux-alpine-amd64-snapshot
- pkl-cli-windows-amd64-snapshot
context: pkl-maven-release
- trigger-docsite-build:
requires:
- deploy-snapshot
context:
- pkl-pr-approval
when:
equal:
- main
- << pipeline.git.branch >>
release:
jobs:
- gradle-check-jdk17:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- gradle-check-jdk21:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- gradle-check-jdk17-windows:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- bench:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- gradle-compatibility:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- pkl-cli-macOS-amd64-release:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- pkl-cli-linux-amd64-release:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- pkl-cli-macOS-aarch64-release:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- pkl-cli-linux-aarch64-release:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- pkl-cli-linux-alpine-amd64-release:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- pkl-cli-windows-amd64-release:
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- github-release:
requires:
- gradle-check-jdk17
- gradle-check-jdk21
- gradle-check-jdk17-windows
- bench
- gradle-compatibility
- pkl-cli-macOS-amd64-release
- pkl-cli-linux-amd64-release
- pkl-cli-macOS-aarch64-release
- pkl-cli-linux-aarch64-release
- pkl-cli-linux-alpine-amd64-release
- pkl-cli-windows-amd64-release
context: pkl-github-release
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- deploy-release:
requires:
- github-release
context: pkl-maven-release
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
- trigger-package-docs-build:
requires:
- deploy-release
context:
- pkl-pr-approval
filters:
branches:
ignore: /.*/
tags:
only: /^v?\d+\.\d+\.\d+$/
release-branch:
jobs:
- gradle-check-jdk17
- gradle-check-jdk21
- gradle-check-jdk17-windows
- bench
- gradle-compatibility
- pkl-cli-macOS-amd64-release
- pkl-cli-linux-amd64-release
- pkl-cli-macOS-aarch64-release
- pkl-cli-linux-aarch64-release
- pkl-cli-linux-alpine-amd64-release
- pkl-cli-windows-amd64-release
when:
matches:
value: << pipeline.git.branch >>
pattern: ^release/\d+\.\d+$

View File

@@ -1,164 +0,0 @@
//===----------------------------------------------------------------------===//
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
/// Builds the native `pkl` CLI
extends "GradleJob.pkl"
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.1.2#/Config.pkl"
import "package://pkg.pkl-lang.org/pkl-pantry/pkl.experimental.uri@1.0.0#/URI.pkl"
/// The architecture to use
arch: "amd64"|"aarch64"
/// Whether to link to musl. Otherwise, links to glibc.
musl: Boolean = false
local setupLinuxEnvironment: Config.RunStep =
let (jdkVersion = "17.0.9+9")
let (muslVersion = "1.2.2")
let (zlibVersion = "1.2.13")
let (jdkVersionEncoded = URI.encodeComponent(jdkVersion))
let (jdkVersionAlt = jdkVersion.replaceLast("+", "_"))
let (majorJdkVersion = jdkVersion.split(".").first)
new {
name = "Set up environment"
shell = "#!/bin/bash -exo pipefail"
command = new Listing {
#"""
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 -L \
https://github.com/adoptium/temurin\#(majorJdkVersion)-binaries/releases/download/jdk-\#(jdkVersionEncoded)/OpenJDK\#(majorJdkVersion)U-jdk_\#(if (arch == "amd64") "x64" else "aarch64")_linux_hotspot_\#(jdkVersionAlt).tar.gz -o /tmp/jdk.tar.gz
mkdir /jdk \
&& cd /jdk \
&& cat /tmp/jdk.tar.gz | tar --strip-components=1 -xzC .
mkdir -p ~/staticdeps/bin
cp /usr/lib/gcc/\#(if (arch == "amd64") "x86_64" else "aarch64")-redhat-linux/8/libstdc++.a ~/staticdeps
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
curl -L https://github.com/madler/zlib/releases/download/v\#(zlibVersion)/zlib-\#(zlibVersion).tar.gz -o /tmp/zlib.tar.gz
mkdir -p /tmp/dep_zlib-\#(zlibVersion) \
&& cd /tmp/dep_zlib-\#(zlibVersion) \
&& cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC . \
&& echo "zlib-\#(zlibVersion): configure..." && ./configure --static --prefix="$HOME"/staticdeps > /dev/null \
&& echo "zlib-\#(zlibVersion): make..." && make -s -j4 \
&& echo "zlib-\#(zlibVersion): make install..." && make -s install \
&& rm -rf /tmp/dep_zlib-\#(zlibVersion)
fi
"""#
// don't need musl on aarch because GraalVM only supports musl builds on x86
when (arch == "amd64") {
#"""
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
curl -L https://musl.libc.org/releases/musl-\#(muslVersion).tar.gz -o /tmp/musl.tar.gz
mkdir -p /tmp/dep_musl-\#(muslVersion) \
&& cd /tmp/dep_musl-\#(muslVersion) \
&& cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC . \
&& echo "musl-\#(muslVersion): configure..." && ./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null \
&& echo "musl-\#(muslVersion): make..." && make -s -j4 \
&& echo "musl-\#(muslVersion): make install..." && make -s install \
&& rm -rf /tmp/dep_musl-\#(muslVersion)
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
"""#
}
}.join("\n\n")
}
steps {
when (os == "linux") {
new Config.RestoreCacheStep {
name = "Restore static deps from cache"
key = "staticdeps-\(arch)"
}
setupLinuxEnvironment
new Config.SaveCacheStep {
name = "Save statics deps to cache"
key = "staticdeps-\(arch)"
paths {
"~/staticdeps"
}
}
}
when (os == "macOS" && arch == "amd64") {
new Config.RunStep {
name = "Installing Rosetta 2"
command = """
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
"""
}
}
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())
"""#
}
new Config.PersistToWorkspaceStep {
root = "."
paths {
"pkl-cli/build/executable/"
}
}
}
job {
when (os == "macOS") {
macos {
xcode = "15.3.0"
}
resource_class = "macos.m1.large.gen1"
}
when (os == "linux") {
docker {
new {
image = if (arch == "aarch64") "arm64v8/oraclelinux:8-slim" else "oraclelinux:8-slim"
}
}
environment {
["JAVA_HOME"] = "/jdk"
}
resource_class = if (arch == "aarch64") "arm.xlarge" else "xlarge"
}
when (os == "windows") {
machine {
image = "windows-server-2022-gui:current"
}
resource_class = "windows.large"
}
}

View File

@@ -1,44 +0,0 @@
//===----------------------------------------------------------------------===//
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
extends "GradleJob.pkl"
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.1.2#/Config.pkl"
local self = this
command: String
job {
docker {
new { image = "cimg/openjdk:17.0" }
}
}
os = "linux"
steps {
new Config.AttachWorkspaceStep { at = "." }
new Config.RunStep {
command = "./gradlew \(self.gradleArgs) \(module.command)"
}
// add jpkl to workspace so it gets published as a GitHub release
new Config.PersistToWorkspaceStep {
root = "."
paths {
"pkl-cli/build/executable/"
}
}
}

View File

@@ -1,45 +0,0 @@
//===----------------------------------------------------------------------===//
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
extends "GradleJob.pkl"
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.1.2#/Config.pkl"
javaVersion: "17.0"|"21.0"
os = "linux"
steps {
new Config.RunStep {
name = "gradle check"
command = "./gradlew \(module.gradleArgs) check"
}
}
job {
when (os == "linux") {
docker {
new {
image = "cimg/openjdk:\(javaVersion)"
}
}
}
when (os == "windows") {
machine {
image = "windows-server-2022-gui:current"
}
resource_class = "windows.large"
}
}

View File

@@ -1,48 +0,0 @@
//===----------------------------------------------------------------------===//
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
abstract module GradleJob
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.1.2#/Config.pkl"
/// Whether this is a release build or not.
isRelease: Boolean = false
/// The OS to run on
os: "macOS"|"linux"|"windows"
fixed gradleArgs = new Listing {
"--info"
"--stacktrace"
"-DtestReportsDir=${HOME}/test-results"
when (isRelease) {
"-DreleaseBuild=true"
}
}.join(" ")
steps: Listing<Config.Step>
job: Config.Job = new {
environment {
["LANG"] = "en_US.UTF-8"
}
steps {
"checkout"
...module.steps
new Config.StoreTestResults {
path = "~/test-results"
}
}
}

View File

@@ -1,39 +0,0 @@
//===----------------------------------------------------------------------===//
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
extends "GradleJob.pkl"
import "package://pkg.pkl-lang.org/pkl-pantry/com.circleci.v2@1.1.2#/Config.pkl"
name: String = command
command: String
os = "linux"
steps {
new Config.RunStep {
name = module.name
command = """
./gradlew \(module.gradleArgs) \(module.command)
"""
}
}
job {
docker {
new { image = "cimg/openjdk:17.0" }
}
}

2
.git-blame-ignore-revs Normal file
View File

@@ -0,0 +1,2 @@
# Auto-format Kotlin code
816cd483c8adf4c04e14236c173a1dc6bd2579ea

1
.gitattributes vendored
View File

@@ -1,5 +1,6 @@
# linguist-generated would suppress files in diffs
**/src/test/files/** linguist-vendored
.github/workflows/* linguist-generated
/docs/** linguist-documentation

View File

@@ -2,7 +2,7 @@
files=`git diff --cached --name-status`
if [[ $files =~ .circleci/config.pkl ]]; then
pkl eval .circleci/config.pkl -o .circleci/config.yml
git add .circleci/config.yml
if [[ $files =~ .github/* ]]; then
pkl eval --project-dir .github/ -m .github .github/index.pkl
git add .github/workflows/
fi

10
.github/PklProject vendored Normal file
View File

@@ -0,0 +1,10 @@
amends "pkl:Project"
dependencies {
["pkl.impl.ghactions"] {
uri = "package://pkg.pkl-lang.org/pkl-project-commons/pkl.impl.ghactions@1.2.0"
}
["gha"] {
uri = "package://pkg.pkl-lang.org/pkl-pantry/com.github.actions@1.2.0"
}
}

33
.github/PklProject.deps.json vendored Normal file
View File

@@ -0,0 +1,33 @@
{
"schemaVersion": 1,
"resolvedDependencies": {
"package://pkg.pkl-lang.org/pkl-pantry/com.github.actions@1": {
"type": "remote",
"uri": "projectpackage://pkg.pkl-lang.org/pkl-pantry/com.github.actions@1.3.0",
"checksums": {
"sha256": "76174cb974310b3d952280b76ed224eb4ee6fd5419bf696ad9a66fba44bd427d"
}
},
"package://pkg.pkl-lang.org/pkl-project-commons/pkl.impl.ghactions@1": {
"type": "remote",
"uri": "projectpackage://pkg.pkl-lang.org/pkl-project-commons/pkl.impl.ghactions@1.2.0",
"checksums": {
"sha256": "2f60e7167eab8728c4f60196fd5b6e9965723797528a859f36eb0ecbd2db2909"
}
},
"package://pkg.pkl-lang.org/pkl-pantry/pkl.experimental.deepToTyped@1": {
"type": "remote",
"uri": "projectpackage://pkg.pkl-lang.org/pkl-pantry/pkl.experimental.deepToTyped@1.1.1",
"checksums": {
"sha256": "1e6e29b441ffdee2605d317f6543a4a604aab5af472b63f0c47d92a3b4b36f7f"
}
},
"package://pkg.pkl-lang.org/pkl-pantry/com.github.dependabot@1": {
"type": "remote",
"uri": "projectpackage://pkg.pkl-lang.org/pkl-pantry/com.github.dependabot@1.0.0",
"checksums": {
"sha256": "02ef6f25bfca5b1d095db73ea15de79d2d2c6832ebcab61e6aba90554382abcb"
}
}
}
}

10
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
ignore:
- dependency-name: '*'
update-types:
- version-update:semver-major
schedule:
interval: weekly

198
.github/index.pkl vendored Normal file
View File

@@ -0,0 +1,198 @@
amends "@pkl.impl.ghactions/PklCI.pkl"
import "@gha/Workflow.pkl"
import "jobs/BuildJavaExecutableJob.pkl"
import "jobs/BuildNativeJob.pkl"
import "jobs/DeployJob.pkl"
import "jobs/GithubRelease.pkl"
import "jobs/GradleJob.pkl"
import "jobs/PklJob.pkl"
import "jobs/SimpleGradleJob.pkl"
triggerDocsBuild = "both"
testReports {
junit {
"**/build/test-results/**/*.xml"
}
html {
"**/build/reports/tests/**/*"
}
excludeJobs {
"bench"
"github-release"
Regex("deploy-.*")
}
}
local baseGradleCheck: SimpleGradleJob = new {
isRelease = false
command = "check"
fetchDepth = 0
}
local gradleCheck = (baseGradleCheck) {
os = "linux"
}
local gradleCheckWindows = (baseGradleCheck) {
os = "windows"
}
local typealias PklJobs = Mapping<String, PklJob>
local toWorkflowJobs: (PklJobs) -> Workflow.Jobs = (it) -> new Workflow.Jobs {
for (k, v in it) {
[k] = v.job
}
}
local gradleCheckJobs: PklJobs = new {
["gradle-check"] = gradleCheck
["gradle-check-windows"] = gradleCheckWindows
}
local buildNativeJobs: Mapping<String, BuildNativeJob> = new {
for (_dist in List("release", "snapshot")) {
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
}
}
}
["\(_project)-alpine-linux-amd64-\(_dist)"] {
arch = "amd64"
os = "linux"
musl = true
isRelease = _dist == "release"
project = _project
}
["\(_project)-windows-amd64-\(_dist)"] {
arch = "amd64"
os = "windows"
isRelease = _dist == "release"
project = _project
}
}
}
}
local buildNativeSnapshots = buildNativeJobs.toMap().filter((key, _) -> key.endsWith("snapshot"))
local buildNativeReleases = buildNativeJobs.toMap().filter((key, _) -> key.endsWith("release"))
local benchmarkJob: SimpleGradleJob = new { command = "bench:jmh" }
local gradleCompatibilityJob: SimpleGradleJob = new {
command = ":pkl-gradle:build :pkl-gradle:compatibilityTestReleases"
fetchDepth = 0
}
local buildJavaExecutableJob: BuildJavaExecutableJob = new {
fetchDepth = 0
}
local buildAndTestJobs: PklJobs = new {
...gradleCheckJobs
["bench"] = benchmarkJob
["gradle-compatibility"] = gradleCompatibilityJob
["java-executables-snapshot"] = (buildJavaExecutableJob) { isRelease = false }
...buildNativeSnapshots
}
local releaseJobs: PklJobs = new {
...gradleCheckJobs
["bench"] = benchmarkJob
["gradle-compatibility"] = gradleCompatibilityJob
["java-executables-release"] = (buildJavaExecutableJob) { isRelease = true }
...buildNativeReleases
}
// By default, just run ./gradlew check on linux.
// Trigger other checks based on GitHub PR description. Examples:
//
// * [windows] -- Test on Windows
// * [native] -- Test all native builds
// * [native-pkl-cli] -- Test all pkl-cli os/arch pairs
// * [native-pkl-cli-macos] -- Test pkl-cli on macOS
prb {
local prbJobs: Mapping<String, GradleJob> = new {
["gradle-check"] = gradleCheck
["gradle-check-windows"] = (gradleCheckWindows) {
`if` = "contains(github.event.pull_request.body, '[windows]')"
}
for (jobName, job in buildNativeSnapshots) {
[jobName] = (job) {
local tags = new Listing {
"[native]"
"[native-\(job.project)]"
"[native-\(job.project)-\(job.os)]"
"[native-\(job.project)-\(job.os)-\(job.arch)]"
"[native-\(job.project)-\(job.os)-\(job.arch)]"
when (job.musl) {
"[native-\(job.project)-alpine-\(job.os)-\(job.arch)]"
}
}
`if` =
tags
.toList()
.map((it) -> "contains(github.event.pull_request.body, '\(it)')")
.join(" || ")
}
}
}
local prbJobs2 = (prbJobs) {
[[true]] {
// better SLA when not running on nightly
nightlyMacOS = false
}
}
jobs = prbJobs2 |> toWorkflowJobs
}
build {
jobs = buildAndTestJobs |> toWorkflowJobs
}
main {
jobs =
(buildAndTestJobs) {
["deploy-snapshot"] = (
new DeployJob {
extraGradleArgs {
"--no-parallel"
}
command = "publishToSonatype"
}
) {
needs = buildAndTestJobs.keys.toListing()
}
} |> toWorkflowJobs
}
releaseBranch {
jobs = releaseJobs |> toWorkflowJobs
}
release {
jobs =
(releaseJobs) {
["deploy-release"] = (
new DeployJob {
isRelease = true
command = "publishToSonatype closeAndReleaseSonatypeStagingRepository"
}
) {
needs = releaseJobs.keys.toListing()
}
["github-release"] = new GithubRelease {
needs = "deploy-release"
}
} |> toWorkflowJobs
}

32
.github/jobs/BuildJavaExecutableJob.pkl vendored Normal file
View File

@@ -0,0 +1,32 @@
extends "GradleJob.pkl"
import "@gha/catalog.pkl"
// Keep this in sync with projects that build java executables
local projects: List<String> = List("pkl-doc", "pkl-cli", "pkl-codegen-java", "pkl-codegen-kotlin")
local command =
new Listing<String> {
"./gradlew"
module.gradleArgs
for (project in projects) {
// NOTE: `build` doesn't build native executables
"\(project):build"
}
}.join(" ")
steps {
catalog.`actions/checkout@v6`
new {
name = "gradle build java executables"
shell = "bash"
run = command
}
(catalog.`actions/upload-artifact@v5`) {
name = "Upload executable artifacts"
with {
name = "executable-java"
path = "*/build/executable/**/*"
}
}
}

72
.github/jobs/BuildNativeJob.pkl vendored Normal file
View File

@@ -0,0 +1,72 @@
extends "GradleJob.pkl"
import "@gha/catalog.pkl"
import "@gha/context.pkl"
/// Whether to link to musl. Otherwise, links to glibc.
musl: Boolean(implies(module.os == "linux")) = false
/// The Gradle project under which to generate the executable
project: String
extraGradleArgs {
when (os == "macOS" && arch == "amd64") {
"-Dpkl.targetArch=\(module.arch)"
"-Dpkl.native--native-compiler-path=\(context.github.workspace)/.github/scripts/cc_macos_amd64.sh"
}
when (musl) {
"-Dpkl.musl=true"
}
}
preSteps {
when (os == "linux" && !musl) {
new {
name = "Install deps"
run = "dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en"
}
}
}
steps {
when (musl) {
new {
name = "Install musl and zlib"
run = read("../scripts/install_musl.sh").text
}
}
// workaround for https://github.com/actions/checkout/issues/1048
when (os == "linux" && !musl) {
new {
name = "Fix git ownership"
// language=bash
run = "git status || git config --system --add safe.directory $GITHUB_WORKSPACE"
}
}
new {
name = "gradle buildNative"
shell = "bash"
run = "./gradlew \(module.gradleArgs) \(project):buildNative"
}
(catalog.`actions/upload-artifact@v5`) {
name = "Upload executable artifacts"
with {
name =
if (musl)
"executable-\(project)-alpine-\(module.os)-\(module.arch)"
else
"executable-\(project)-\(module.os)-\(module.arch)"
// Need to insert a wildcard to make actions/upload-artifact preserve the folder hierarchy.
// See https://github.com/actions/upload-artifact/issues/206
path = "\(project)*/build/executable/**/*"
}
}
}
fixed job {
when (os == "linux" && !musl) {
container {
image = "redhat/ubi8:8.10"
}
}
}

31
.github/jobs/DeployJob.pkl vendored Normal file
View File

@@ -0,0 +1,31 @@
extends "GradleJob.pkl"
import "@gha/catalog.pkl"
import "@gha/Workflow.pkl"
import "@pkl.impl.ghactions/helpers.pkl"
local self = this
command: String
arch = "amd64"
os = "linux"
steps {
catalog.`actions/checkout@v6`
(catalog.`actions/download-artifact@v6`) {
with {
pattern = "executable-**"
`merge-multiple` = true
}
}
new Workflow.Step {
run = "./gradlew \(self.gradleArgs) \(module.command)"
}
|> helpers.withMavenPublishSecrets
}
fixed job {
environment = "maven-release"
}

44
.github/jobs/GithubRelease.pkl vendored Normal file
View File

@@ -0,0 +1,44 @@
module GithubRelease
extends "PklJob.pkl"
import "@gha/catalog.pkl"
import "@gha/context.pkl"
fixed job {
`runs-on` = "ubuntu-latest"
permissions {
contents = "write"
}
needs = "deploy-release"
steps {
(catalog.`actions/download-artifact@v6`) {
with {
pattern = "executable-**"
`merge-multiple` = true
}
}
new {
name = "Publish release on GitHub"
env {
["GH_TOKEN"] = context.github.token
["TAG_NAME"] = context.github.refName
["GIT_SHA"] = context.github.sha
["GH_REPO"] = context.github.repository
}
// language=bash
run =
#"""
# exclude build_artifacts.txt from publish
rm -f */build/executable/*.build_artifacts.txt
find */build/executable/* -type d | xargs rm -rf
gh release create ${TAG_NAME} \
--title "${TAG_NAME}" \
--target "${GIT_SHA}" \
--verify-tag \
--notes "Release notes: https://pkl-lang.org/main/current/release-notes/changelog.html#release-${TAG_NAME}" \
*/build/executable/*
"""#
}
}
}

96
.github/jobs/GradleJob.pkl vendored Normal file
View File

@@ -0,0 +1,96 @@
abstract module GradleJob
extends "PklJob.pkl"
import "@gha/Workflow.pkl"
import "@pkl.impl.ghactions/catalog.pkl"
/// Whether this is a release build or not.
isRelease: Boolean = false
/// The architecture to use
arch: "amd64" | "aarch64" = "amd64"
/// The OS to run on.
os: "macOS" | "linux" | "windows" = "linux"
// TODO flip this to `true` when nightly macOS is available
/// Whether to run on nightly macOS.
nightlyMacOS: Boolean(implies(os == "macOS")) = false
extraGradleArgs: Listing<String>
steps: Listing<Workflow.Step>
preSteps: Listing<Workflow.Step>
/// The fetch depth to use when doing a git checkout.
fetchDepth: Int?
fixed gradleArgs =
new Listing {
"--info"
"--stacktrace"
"--no-daemon"
"-DpklMultiJdkTesting=true"
when (isRelease) {
"-DreleaseBuild=true"
}
...extraGradleArgs
}.join(" ")
fixed job {
env {
["LANG"] = "en_US.UTF-8"
when (os == "windows") {
["JAVA_HOME"] = "/jdk"
}
}
when (os == "macOS") {
`if` =
let (cond = "github.repository_owner == 'apple'")
if (super.`if` != null)
"(\(super.`if`)) && \(cond)"
else
cond
}
`runs-on` =
if (os == "linux" && arch == "amd64")
"ubuntu-latest"
else if (os == "linux" && arch == "aarch64")
"ubuntu-24.04-arm"
else if (os == "windows")
"windows-latest"
else
new Listing {
"self-hosted"
"macos"
when (nightlyMacOS) {
"nightly"
}
}
steps {
...preSteps
// full checkout (needed for spotless)
(catalog.`actions/checkout@v6`) {
when (fetchDepth != null) {
with {
`fetch-depth` = fetchDepth
}
}
}
(catalog.`actions/setup-java@v5`) {
with {
`java-version` = "21"
distribution = "temurin"
architecture =
if (arch == "amd64")
"x64"
else
"aarch64"
}
}
catalog.`gradle/actions/setup-gradle@v5`
...module.steps
}
}

29
.github/jobs/PklJob.pkl vendored Normal file
View File

@@ -0,0 +1,29 @@
abstract module PklJob
extends "@pkl.impl.ghactions/jobs/PklJob.pkl"
/// Identify any jobs that must complete successfully before this job will run.
///
/// It can be a string or array of strings.
/// If a job fails or is skipped, all jobs that need it are skipped unless the jobs use a conditional expression that
/// causes the job to continue.
/// If a run contains a series of jobs that need each other, a failure or skip applies to all jobs in the dependency
/// chain from the point of failure or skip onwards. If you would like a job to run even if a job it is dependent on
/// did not succeed, use the `always()` conditional expression in `jobs.<job_id>.if`.
///
/// See: <https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idneeds>
needs: (String | *Listing<String>)?
/// A conditional to prevent a job from running unless a condition is met.
///
/// You can use any supported context and expression to create a conditional.
/// For more information on which contexts are supported in this key, see
/// [Contexts reference](https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#context-availability).
@SourceCode { language = "GithubExpressionLanguage" }
`if`: String?
/// The underlying workflow job
fixed job {
`if` = module.`if`
needs = module.needs
}

18
.github/jobs/SimpleGradleJob.pkl vendored Normal file
View File

@@ -0,0 +1,18 @@
extends "GradleJob.pkl"
name: String = command
command: String
os = "linux"
steps {
new {
name = module.name
shell = "bash"
run =
"""
./gradlew \(module.gradleArgs) \(module.command)
"""
}
}

2
.github/scripts/cc_macos_amd64.sh vendored Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env bash
clang -arch x86_64 "$@"

71
.github/scripts/install_musl.sh vendored Normal file
View File

@@ -0,0 +1,71 @@
set -e
mkdir -p ~/staticdeps/
ZLIB_VERSION="1.2.13"
MUSL_VERSION="1.2.5"
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
# Download zlib tarball and signature
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
# Import zlib GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
# Verify GPG signature
echo "Verifying zlib GPG signature..."
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
# shellcheck disable=SC2002
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
echo "zlib-${ZLIB_VERSION}: configure..."
./configure --static --prefix="$HOME"/staticdeps > /dev/null
echo "zlib-${ZLIB_VERSION}: make..."
make -s -j4
echo "zlib-${ZLIB_VERSION}: make install..."
make -s install
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
# Download musl tarball and signature
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
# Import musl GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
# Verify GPG signature
echo "Verifying musl GPG signature..."
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
cd "/tmp/dep_musl-${MUSL_VERSION}"
# shellcheck disable=SC2002
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
echo "musl-${MUSL_VERSION}: configure..."
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
echo "musl-${MUSL_VERSION}: make..."
make -s -j4
echo "musl-${MUSL_VERSION}: make install..."
make -s install
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"

33
.github/workflows/__lockfile__.yml generated vendored Normal file
View File

@@ -0,0 +1,33 @@
#file: noinspection MandatoryParamsAbsent,UndefinedAction
# This is a fake workflow that never runs.
# It's used to pin actions to specific git SHAs when generating actual workflows.
# It also gets updated by dependabot (see .github/dependabot.yml).
# Generated from Workflow.pkl. DO NOT EDIT.
name: __lockfile__
'on':
push:
branches-ignore:
- '**'
tags-ignore:
- '**'
jobs:
locks:
if: 'false'
runs-on: nothing
steps:
- name: EnricoMi/publish-unit-test-result-action@v2
uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2
- name: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
- name: actions/create-github-app-token@v2
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2
- name: actions/download-artifact@v6
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
- name: actions/setup-java@v5
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
- name: actions/upload-artifact@v5
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
- name: dawidd6/action-download-artifact@v11
uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11
- name: gradle/actions/setup-gradle@v5
uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5

825
.github/workflows/build.yml generated vendored Normal file
View File

@@ -0,0 +1,825 @@
# Generated from Workflow.pkl. DO NOT EDIT.
name: Build
'on':
push:
branches-ignore:
- main
- release/*
tags-ignore:
- '**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: read
jobs:
gradle-check:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: check
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true check
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-check
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-check
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
gradle-check-windows:
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: check
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true check
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-check-windows
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-check-windows
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
bench:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: bench:jmh
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true bench:jmh
gradle-compatibility:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: :pkl-gradle:build :pkl-gradle:compatibilityTestReleases
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true :pkl-gradle:build :pkl-gradle:compatibilityTestReleases
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-compatibility
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-compatibility
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
java-executables-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- name: gradle build java executables
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:build pkl-cli:build pkl-codegen-java:build pkl-codegen-kotlin:build
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-java
path: '*/build/executable/**/*'
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-java-executables-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-java-executables-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-macOS-amd64-snapshot:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.targetArch=amd64 -Dpkl.native--native-compiler-path=${{ github.workspace }}/.github/scripts/cc_macos_amd64.sh pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-macOS-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-macOS-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-macOS-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-linux-amd64-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-linux-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-cli-macOS-aarch64-snapshot:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-macOS-aarch64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-macOS-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-macOS-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-linux-aarch64-snapshot:
runs-on: ubuntu-24.04-arm
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-linux-aarch64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-linux-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-linux-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-cli-alpine-linux-amd64-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Install musl and zlib
run: |
set -e
mkdir -p ~/staticdeps/
ZLIB_VERSION="1.2.13"
MUSL_VERSION="1.2.5"
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
# Download zlib tarball and signature
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
# Import zlib GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
# Verify GPG signature
echo "Verifying zlib GPG signature..."
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
# shellcheck disable=SC2002
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
echo "zlib-${ZLIB_VERSION}: configure..."
./configure --static --prefix="$HOME"/staticdeps > /dev/null
echo "zlib-${ZLIB_VERSION}: make..."
make -s -j4
echo "zlib-${ZLIB_VERSION}: make install..."
make -s install
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
# Download musl tarball and signature
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
# Import musl GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
# Verify GPG signature
echo "Verifying musl GPG signature..."
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
cd "/tmp/dep_musl-${MUSL_VERSION}"
# shellcheck disable=SC2002
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
echo "musl-${MUSL_VERSION}: configure..."
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
echo "musl-${MUSL_VERSION}: make..."
make -s -j4
echo "musl-${MUSL_VERSION}: make install..."
make -s install
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-alpine-linux-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-alpine-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-alpine-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-windows-amd64-snapshot:
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-windows-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-windows-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-windows-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-macOS-amd64-snapshot:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.targetArch=amd64 -Dpkl.native--native-compiler-path=${{ github.workspace }}/.github/scripts/cc_macos_amd64.sh pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-macOS-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-macOS-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-macOS-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-linux-amd64-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-linux-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-doc-macOS-aarch64-snapshot:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-macOS-aarch64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-macOS-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-macOS-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-linux-aarch64-snapshot:
runs-on: ubuntu-24.04-arm
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-linux-aarch64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-linux-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-linux-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-doc-alpine-linux-amd64-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Install musl and zlib
run: |
set -e
mkdir -p ~/staticdeps/
ZLIB_VERSION="1.2.13"
MUSL_VERSION="1.2.5"
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
# Download zlib tarball and signature
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
# Import zlib GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
# Verify GPG signature
echo "Verifying zlib GPG signature..."
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
# shellcheck disable=SC2002
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
echo "zlib-${ZLIB_VERSION}: configure..."
./configure --static --prefix="$HOME"/staticdeps > /dev/null
echo "zlib-${ZLIB_VERSION}: make..."
make -s -j4
echo "zlib-${ZLIB_VERSION}: make install..."
make -s install
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
# Download musl tarball and signature
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
# Import musl GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
# Verify GPG signature
echo "Verifying musl GPG signature..."
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
cd "/tmp/dep_musl-${MUSL_VERSION}"
# shellcheck disable=SC2002
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
echo "musl-${MUSL_VERSION}: configure..."
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
echo "musl-${MUSL_VERSION}: make..."
make -s -j4
echo "musl-${MUSL_VERSION}: make install..."
make -s install
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-alpine-linux-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-alpine-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-alpine-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-windows-amd64-snapshot:
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-windows-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-windows-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-windows-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
publish-test-results:
if: '!cancelled()'
needs:
- gradle-check
- gradle-check-windows
- gradle-compatibility
- java-executables-snapshot
- pkl-cli-macOS-amd64-snapshot
- pkl-cli-linux-amd64-snapshot
- pkl-cli-macOS-aarch64-snapshot
- pkl-cli-linux-aarch64-snapshot
- pkl-cli-alpine-linux-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-alpine-linux-amd64-snapshot
- pkl-doc-windows-amd64-snapshot
permissions:
checks: write
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
pattern: test-results-xml-*
- name: Publish test results
if: '!cancelled()'
uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2
with:
comment_mode: 'off'
files: test-results-xml-*/**/*.xml
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-publish-test-results
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore

912
.github/workflows/main.yml generated vendored Normal file
View File

@@ -0,0 +1,912 @@
# Generated from Workflow.pkl. DO NOT EDIT.
name: Build (main)
'on':
push:
branches:
- main
tags-ignore:
- '**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: read
jobs:
gradle-check:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: check
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true check
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-check
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-check
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
gradle-check-windows:
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: check
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true check
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-check-windows
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-check-windows
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
bench:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: bench:jmh
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true bench:jmh
gradle-compatibility:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: :pkl-gradle:build :pkl-gradle:compatibilityTestReleases
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true :pkl-gradle:build :pkl-gradle:compatibilityTestReleases
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-compatibility
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-compatibility
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
java-executables-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- name: gradle build java executables
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:build pkl-cli:build pkl-codegen-java:build pkl-codegen-kotlin:build
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-java
path: '*/build/executable/**/*'
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-java-executables-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-java-executables-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-macOS-amd64-snapshot:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.targetArch=amd64 -Dpkl.native--native-compiler-path=${{ github.workspace }}/.github/scripts/cc_macos_amd64.sh pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-macOS-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-macOS-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-macOS-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-linux-amd64-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-linux-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-cli-macOS-aarch64-snapshot:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-macOS-aarch64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-macOS-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-macOS-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-linux-aarch64-snapshot:
runs-on: ubuntu-24.04-arm
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-linux-aarch64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-linux-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-linux-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-cli-alpine-linux-amd64-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Install musl and zlib
run: |
set -e
mkdir -p ~/staticdeps/
ZLIB_VERSION="1.2.13"
MUSL_VERSION="1.2.5"
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
# Download zlib tarball and signature
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
# Import zlib GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
# Verify GPG signature
echo "Verifying zlib GPG signature..."
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
# shellcheck disable=SC2002
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
echo "zlib-${ZLIB_VERSION}: configure..."
./configure --static --prefix="$HOME"/staticdeps > /dev/null
echo "zlib-${ZLIB_VERSION}: make..."
make -s -j4
echo "zlib-${ZLIB_VERSION}: make install..."
make -s install
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
# Download musl tarball and signature
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
# Import musl GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
# Verify GPG signature
echo "Verifying musl GPG signature..."
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
cd "/tmp/dep_musl-${MUSL_VERSION}"
# shellcheck disable=SC2002
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
echo "musl-${MUSL_VERSION}: configure..."
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
echo "musl-${MUSL_VERSION}: make..."
make -s -j4
echo "musl-${MUSL_VERSION}: make install..."
make -s install
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-alpine-linux-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-alpine-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-alpine-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-windows-amd64-snapshot:
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-windows-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-windows-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-windows-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-macOS-amd64-snapshot:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.targetArch=amd64 -Dpkl.native--native-compiler-path=${{ github.workspace }}/.github/scripts/cc_macos_amd64.sh pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-macOS-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-macOS-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-macOS-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-linux-amd64-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-linux-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-doc-macOS-aarch64-snapshot:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-macOS-aarch64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-macOS-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-macOS-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-linux-aarch64-snapshot:
runs-on: ubuntu-24.04-arm
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-linux-aarch64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-linux-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-linux-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-doc-alpine-linux-amd64-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Install musl and zlib
run: |
set -e
mkdir -p ~/staticdeps/
ZLIB_VERSION="1.2.13"
MUSL_VERSION="1.2.5"
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
# Download zlib tarball and signature
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
# Import zlib GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
# Verify GPG signature
echo "Verifying zlib GPG signature..."
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
# shellcheck disable=SC2002
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
echo "zlib-${ZLIB_VERSION}: configure..."
./configure --static --prefix="$HOME"/staticdeps > /dev/null
echo "zlib-${ZLIB_VERSION}: make..."
make -s -j4
echo "zlib-${ZLIB_VERSION}: make install..."
make -s install
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
# Download musl tarball and signature
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
# Import musl GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
# Verify GPG signature
echo "Verifying musl GPG signature..."
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
cd "/tmp/dep_musl-${MUSL_VERSION}"
# shellcheck disable=SC2002
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
echo "musl-${MUSL_VERSION}: configure..."
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
echo "musl-${MUSL_VERSION}: make..."
make -s -j4
echo "musl-${MUSL_VERSION}: make install..."
make -s install
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-alpine-linux-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-alpine-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-alpine-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-windows-amd64-snapshot:
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-windows-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-windows-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-windows-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
deploy-snapshot:
needs:
- gradle-check
- gradle-check-windows
- bench
- gradle-compatibility
- java-executables-snapshot
- pkl-cli-macOS-amd64-snapshot
- pkl-cli-linux-amd64-snapshot
- pkl-cli-macOS-aarch64-snapshot
- pkl-cli-linux-aarch64-snapshot
- pkl-cli-alpine-linux-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-alpine-linux-amd64-snapshot
- pkl-doc-windows-amd64-snapshot
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
environment: maven-release
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
pattern: executable-**
merge-multiple: true
- env:
ORG_GRADLE_PROJECT_signingKeyId: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGKEYID }}
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGKEY }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGPASSWORD }}
ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPEPASSWORD }}
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPEUSERNAME }}
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true --no-parallel publishToSonatype
publish-test-results:
if: '!cancelled()'
needs:
- gradle-check
- gradle-check-windows
- gradle-compatibility
- java-executables-snapshot
- pkl-cli-macOS-amd64-snapshot
- pkl-cli-linux-amd64-snapshot
- pkl-cli-macOS-aarch64-snapshot
- pkl-cli-linux-aarch64-snapshot
- pkl-cli-alpine-linux-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-alpine-linux-amd64-snapshot
- pkl-doc-windows-amd64-snapshot
permissions:
checks: write
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
pattern: test-results-xml-*
- name: Publish test results
if: '!cancelled()'
uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2
with:
comment_mode: 'off'
files: test-results-xml-*/**/*.xml
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-publish-test-results
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
trigger-downstream-builds:
if: github.repository_owner == 'apple'
needs:
- gradle-check
- gradle-check-windows
- bench
- gradle-compatibility
- java-executables-snapshot
- pkl-cli-macOS-amd64-snapshot
- pkl-cli-linux-amd64-snapshot
- pkl-cli-macOS-aarch64-snapshot
- pkl-cli-linux-aarch64-snapshot
- pkl-cli-alpine-linux-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-alpine-linux-amd64-snapshot
- pkl-doc-windows-amd64-snapshot
- deploy-snapshot
- publish-test-results
runs-on: ubuntu-latest
steps:
- name: Create app token
id: app-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2
with:
app-id: ${{ secrets.PKL_CI_CLIENT_ID }}
private-key: ${{ secrets.PKL_CI }}
owner: ${{ github.repository_owner }}
- name: Trigger pkl-lang.org build
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |-
gh workflow run \
--repo apple/pkl-lang.org \
--ref main \
--field source_run="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
main.yml

753
.github/workflows/prb.yml generated vendored Normal file
View File

@@ -0,0 +1,753 @@
# Generated from Workflow.pkl. DO NOT EDIT.
name: Pull Request
'on':
pull_request: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
gradle-check:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: check
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true check
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-check
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-check
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
gradle-check-windows:
if: contains(github.event.pull_request.body, '[windows]')
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: check
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true check
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-check-windows
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-check-windows
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-macOS-amd64-snapshot:
if: (contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-pkl-cli]') || contains(github.event.pull_request.body, '[native-pkl-cli-macOS]') || contains(github.event.pull_request.body, '[native-pkl-cli-macOS-amd64]') || contains(github.event.pull_request.body, '[native-pkl-cli-macOS-amd64]')) && github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.targetArch=amd64 -Dpkl.native--native-compiler-path=${{ github.workspace }}/.github/scripts/cc_macos_amd64.sh pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-macOS-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-macOS-amd64-snapshot
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-macOS-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-linux-amd64-snapshot:
if: contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-pkl-cli]') || contains(github.event.pull_request.body, '[native-pkl-cli-linux]') || contains(github.event.pull_request.body, '[native-pkl-cli-linux-amd64]') || contains(github.event.pull_request.body, '[native-pkl-cli-linux-amd64]')
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-linux-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-cli-macOS-aarch64-snapshot:
if: (contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-pkl-cli]') || contains(github.event.pull_request.body, '[native-pkl-cli-macOS]') || contains(github.event.pull_request.body, '[native-pkl-cli-macOS-aarch64]') || contains(github.event.pull_request.body, '[native-pkl-cli-macOS-aarch64]')) && github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-macOS-aarch64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-macOS-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-macOS-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-linux-aarch64-snapshot:
if: contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-pkl-cli]') || contains(github.event.pull_request.body, '[native-pkl-cli-linux]') || contains(github.event.pull_request.body, '[native-pkl-cli-linux-aarch64]') || contains(github.event.pull_request.body, '[native-pkl-cli-linux-aarch64]')
runs-on: ubuntu-24.04-arm
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-linux-aarch64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-linux-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-linux-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-cli-alpine-linux-amd64-snapshot:
if: contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-pkl-cli]') || contains(github.event.pull_request.body, '[native-pkl-cli-linux]') || contains(github.event.pull_request.body, '[native-pkl-cli-linux-amd64]') || contains(github.event.pull_request.body, '[native-pkl-cli-linux-amd64]') || contains(github.event.pull_request.body, '[native-pkl-cli-alpine-linux-amd64]')
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Install musl and zlib
run: |
set -e
mkdir -p ~/staticdeps/
ZLIB_VERSION="1.2.13"
MUSL_VERSION="1.2.5"
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
# Download zlib tarball and signature
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
# Import zlib GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
# Verify GPG signature
echo "Verifying zlib GPG signature..."
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
# shellcheck disable=SC2002
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
echo "zlib-${ZLIB_VERSION}: configure..."
./configure --static --prefix="$HOME"/staticdeps > /dev/null
echo "zlib-${ZLIB_VERSION}: make..."
make -s -j4
echo "zlib-${ZLIB_VERSION}: make install..."
make -s install
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
# Download musl tarball and signature
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
# Import musl GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
# Verify GPG signature
echo "Verifying musl GPG signature..."
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
cd "/tmp/dep_musl-${MUSL_VERSION}"
# shellcheck disable=SC2002
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
echo "musl-${MUSL_VERSION}: configure..."
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
echo "musl-${MUSL_VERSION}: make..."
make -s -j4
echo "musl-${MUSL_VERSION}: make install..."
make -s install
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-alpine-linux-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-alpine-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-alpine-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-windows-amd64-snapshot:
if: contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-pkl-cli]') || contains(github.event.pull_request.body, '[native-pkl-cli-windows]') || contains(github.event.pull_request.body, '[native-pkl-cli-windows-amd64]') || contains(github.event.pull_request.body, '[native-pkl-cli-windows-amd64]')
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-windows-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-windows-amd64-snapshot
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-windows-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-macOS-amd64-snapshot:
if: (contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-pkl-doc]') || contains(github.event.pull_request.body, '[native-pkl-doc-macOS]') || contains(github.event.pull_request.body, '[native-pkl-doc-macOS-amd64]') || contains(github.event.pull_request.body, '[native-pkl-doc-macOS-amd64]')) && github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.targetArch=amd64 -Dpkl.native--native-compiler-path=${{ github.workspace }}/.github/scripts/cc_macos_amd64.sh pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-macOS-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-macOS-amd64-snapshot
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-macOS-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-linux-amd64-snapshot:
if: contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-pkl-doc]') || contains(github.event.pull_request.body, '[native-pkl-doc-linux]') || contains(github.event.pull_request.body, '[native-pkl-doc-linux-amd64]') || contains(github.event.pull_request.body, '[native-pkl-doc-linux-amd64]')
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-linux-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-doc-macOS-aarch64-snapshot:
if: (contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-pkl-doc]') || contains(github.event.pull_request.body, '[native-pkl-doc-macOS]') || contains(github.event.pull_request.body, '[native-pkl-doc-macOS-aarch64]') || contains(github.event.pull_request.body, '[native-pkl-doc-macOS-aarch64]')) && github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-macOS-aarch64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-macOS-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-macOS-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-linux-aarch64-snapshot:
if: contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-pkl-doc]') || contains(github.event.pull_request.body, '[native-pkl-doc-linux]') || contains(github.event.pull_request.body, '[native-pkl-doc-linux-aarch64]') || contains(github.event.pull_request.body, '[native-pkl-doc-linux-aarch64]')
runs-on: ubuntu-24.04-arm
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-linux-aarch64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-linux-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-linux-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-doc-alpine-linux-amd64-snapshot:
if: contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-pkl-doc]') || contains(github.event.pull_request.body, '[native-pkl-doc-linux]') || contains(github.event.pull_request.body, '[native-pkl-doc-linux-amd64]') || contains(github.event.pull_request.body, '[native-pkl-doc-linux-amd64]') || contains(github.event.pull_request.body, '[native-pkl-doc-alpine-linux-amd64]')
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Install musl and zlib
run: |
set -e
mkdir -p ~/staticdeps/
ZLIB_VERSION="1.2.13"
MUSL_VERSION="1.2.5"
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
# Download zlib tarball and signature
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
# Import zlib GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
# Verify GPG signature
echo "Verifying zlib GPG signature..."
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
# shellcheck disable=SC2002
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
echo "zlib-${ZLIB_VERSION}: configure..."
./configure --static --prefix="$HOME"/staticdeps > /dev/null
echo "zlib-${ZLIB_VERSION}: make..."
make -s -j4
echo "zlib-${ZLIB_VERSION}: make install..."
make -s install
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
# Download musl tarball and signature
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
# Import musl GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
# Verify GPG signature
echo "Verifying musl GPG signature..."
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
cd "/tmp/dep_musl-${MUSL_VERSION}"
# shellcheck disable=SC2002
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
echo "musl-${MUSL_VERSION}: configure..."
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
echo "musl-${MUSL_VERSION}: make..."
make -s -j4
echo "musl-${MUSL_VERSION}: make install..."
make -s install
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-alpine-linux-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-alpine-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-alpine-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-windows-amd64-snapshot:
if: contains(github.event.pull_request.body, '[native]') || contains(github.event.pull_request.body, '[native-pkl-doc]') || contains(github.event.pull_request.body, '[native-pkl-doc-windows]') || contains(github.event.pull_request.body, '[native-pkl-doc-windows-amd64]') || contains(github.event.pull_request.body, '[native-pkl-doc-windows-amd64]')
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-windows-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-windows-amd64-snapshot
path: '**/build/test-results/**/*.xml'
if-no-files-found: ignore
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-windows-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
upload-event-file:
runs-on: ubuntu-latest
steps:
- name: Upload event file
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-event-file
path: ${{ github.event_path }}
check-pkl-github-actions:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- name: Setup Pkl
id: setup-pkl
env:
PKL_VERSION: 0.30.0
PKL_FILENAME: pkl
PKL_DOWNLOAD_URL: https://github.com/apple/pkl/releases/download/0.30.0/pkl-linux-amd64
shell: bash
run: |-
DIR="$(mktemp -d /tmp/pkl-$PKL_VERSION-XXXXXX)"
PKL_EXEC="$DIR/$PKL_FILENAME"
curl -sfL -o $PKL_EXEC "$PKL_DOWNLOAD_URL"
chmod +x $PKL_EXEC
echo "$DIR" >> "$GITHUB_PATH"
echo "pkl_exec=$PKL_EXEC" >> "$GITHUB_OUTPUT"
- shell: bash
run: pkl eval -m .github/ --project-dir .github/ .github/index.pkl
- name: check git status
shell: bash
run: |-
if [ -n "$(git status --porcelain)" ]; then
echo "Running pkl resulted in a diff! You likely need to run 'pkl eval' and commit the changes."
git diff --name-only
exit 1
fi

863
.github/workflows/release-branch.yml generated vendored Normal file
View File

@@ -0,0 +1,863 @@
# Generated from Workflow.pkl. DO NOT EDIT.
name: Build (release branch)
'on':
push:
branches:
- release/*
tags-ignore:
- '**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
gradle-check:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: check
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true check
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-check
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-check
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
gradle-check-windows:
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: check
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true check
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-check-windows
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-check-windows
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
bench:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: bench:jmh
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true bench:jmh
gradle-compatibility:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: :pkl-gradle:build :pkl-gradle:compatibilityTestReleases
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true :pkl-gradle:build :pkl-gradle:compatibilityTestReleases
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-compatibility
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-compatibility
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
java-executables-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- name: gradle build java executables
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:build pkl-cli:build pkl-codegen-java:build pkl-codegen-kotlin:build
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-java
path: '*/build/executable/**/*'
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-java-executables-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-java-executables-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-macOS-amd64-snapshot:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.targetArch=amd64 -Dpkl.native--native-compiler-path=${{ github.workspace }}/.github/scripts/cc_macos_amd64.sh pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-macOS-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-macOS-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-macOS-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-linux-amd64-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-linux-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-cli-macOS-aarch64-snapshot:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-macOS-aarch64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-macOS-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-macOS-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-linux-aarch64-snapshot:
runs-on: ubuntu-24.04-arm
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-linux-aarch64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-linux-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-linux-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-cli-alpine-linux-amd64-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Install musl and zlib
run: |
set -e
mkdir -p ~/staticdeps/
ZLIB_VERSION="1.2.13"
MUSL_VERSION="1.2.5"
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
# Download zlib tarball and signature
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
# Import zlib GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
# Verify GPG signature
echo "Verifying zlib GPG signature..."
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
# shellcheck disable=SC2002
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
echo "zlib-${ZLIB_VERSION}: configure..."
./configure --static --prefix="$HOME"/staticdeps > /dev/null
echo "zlib-${ZLIB_VERSION}: make..."
make -s -j4
echo "zlib-${ZLIB_VERSION}: make install..."
make -s install
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
# Download musl tarball and signature
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
# Import musl GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
# Verify GPG signature
echo "Verifying musl GPG signature..."
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
cd "/tmp/dep_musl-${MUSL_VERSION}"
# shellcheck disable=SC2002
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
echo "musl-${MUSL_VERSION}: configure..."
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
echo "musl-${MUSL_VERSION}: make..."
make -s -j4
echo "musl-${MUSL_VERSION}: make install..."
make -s install
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-alpine-linux-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-alpine-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-alpine-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-windows-amd64-snapshot:
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-windows-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-windows-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-windows-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-macOS-amd64-snapshot:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.targetArch=amd64 -Dpkl.native--native-compiler-path=${{ github.workspace }}/.github/scripts/cc_macos_amd64.sh pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-macOS-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-macOS-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-macOS-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-linux-amd64-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-linux-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-doc-macOS-aarch64-snapshot:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-macOS-aarch64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-macOS-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-macOS-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-linux-aarch64-snapshot:
runs-on: ubuntu-24.04-arm
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-linux-aarch64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-linux-aarch64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-linux-aarch64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-doc-alpine-linux-amd64-snapshot:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Install musl and zlib
run: |
set -e
mkdir -p ~/staticdeps/
ZLIB_VERSION="1.2.13"
MUSL_VERSION="1.2.5"
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
# Download zlib tarball and signature
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
# Import zlib GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
# Verify GPG signature
echo "Verifying zlib GPG signature..."
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
# shellcheck disable=SC2002
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
echo "zlib-${ZLIB_VERSION}: configure..."
./configure --static --prefix="$HOME"/staticdeps > /dev/null
echo "zlib-${ZLIB_VERSION}: make..."
make -s -j4
echo "zlib-${ZLIB_VERSION}: make install..."
make -s install
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
# Download musl tarball and signature
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
# Import musl GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
# Verify GPG signature
echo "Verifying musl GPG signature..."
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
cd "/tmp/dep_musl-${MUSL_VERSION}"
# shellcheck disable=SC2002
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
echo "musl-${MUSL_VERSION}: configure..."
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
echo "musl-${MUSL_VERSION}: make..."
make -s -j4
echo "musl-${MUSL_VERSION}: make install..."
make -s install
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -Dpkl.musl=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-alpine-linux-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-alpine-linux-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-alpine-linux-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-windows-amd64-snapshot:
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-windows-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-windows-amd64-snapshot
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-windows-amd64-snapshot
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
publish-test-results:
if: '!cancelled()'
needs:
- gradle-check
- gradle-check-windows
- gradle-compatibility
- java-executables-snapshot
- pkl-cli-macOS-amd64-snapshot
- pkl-cli-linux-amd64-snapshot
- pkl-cli-macOS-aarch64-snapshot
- pkl-cli-linux-aarch64-snapshot
- pkl-cli-alpine-linux-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-alpine-linux-amd64-snapshot
- pkl-doc-windows-amd64-snapshot
permissions:
checks: write
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
pattern: test-results-xml-*
- name: Publish test results
if: '!cancelled()'
uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2
with:
comment_mode: 'off'
files: test-results-xml-*/**/*.xml
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-publish-test-results
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
trigger-downstream-builds:
if: github.repository_owner == 'apple'
needs:
- gradle-check
- gradle-check-windows
- bench
- gradle-compatibility
- java-executables-snapshot
- pkl-cli-macOS-amd64-snapshot
- pkl-cli-linux-amd64-snapshot
- pkl-cli-macOS-aarch64-snapshot
- pkl-cli-linux-aarch64-snapshot
- pkl-cli-alpine-linux-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-alpine-linux-amd64-snapshot
- pkl-doc-windows-amd64-snapshot
- publish-test-results
runs-on: ubuntu-latest
steps:
- name: Create app token
id: app-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2
with:
app-id: ${{ secrets.PKL_CI_CLIENT_ID }}
private-key: ${{ secrets.PKL_CI }}
owner: ${{ github.repository_owner }}
- name: Trigger pkl-lang.org build
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |-
gh workflow run \
--repo apple/pkl-lang.org \
--ref main \
--field source_run="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
main.yml

939
.github/workflows/release.yml generated vendored Normal file
View File

@@ -0,0 +1,939 @@
# Generated from Workflow.pkl. DO NOT EDIT.
name: Release
'on':
push:
branches-ignore:
- '**'
tags:
- '**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: read
jobs:
gradle-check:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: check
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true check
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-check
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-check
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
gradle-check-windows:
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: check
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true check
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-check-windows
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-check-windows
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
bench:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: bench:jmh
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true bench:jmh
gradle-compatibility:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: :pkl-gradle:build :pkl-gradle:compatibilityTestReleases
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true :pkl-gradle:build :pkl-gradle:compatibilityTestReleases
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-gradle-compatibility
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-gradle-compatibility
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
java-executables-release:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- name: gradle build java executables
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:build pkl-cli:build pkl-codegen-java:build pkl-codegen-kotlin:build
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-java
path: '*/build/executable/**/*'
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-java-executables-release
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-java-executables-release
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-macOS-amd64-release:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true -Dpkl.targetArch=amd64 -Dpkl.native--native-compiler-path=${{ github.workspace }}/.github/scripts/cc_macos_amd64.sh pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-macOS-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-macOS-amd64-release
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-macOS-amd64-release
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-linux-amd64-release:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-linux-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-linux-amd64-release
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-linux-amd64-release
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-cli-macOS-aarch64-release:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-macOS-aarch64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-macOS-aarch64-release
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-macOS-aarch64-release
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-linux-aarch64-release:
runs-on: ubuntu-24.04-arm
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-linux-aarch64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-linux-aarch64-release
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-linux-aarch64-release
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-cli-alpine-linux-amd64-release:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Install musl and zlib
run: |
set -e
mkdir -p ~/staticdeps/
ZLIB_VERSION="1.2.13"
MUSL_VERSION="1.2.5"
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
# Download zlib tarball and signature
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
# Import zlib GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
# Verify GPG signature
echo "Verifying zlib GPG signature..."
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
# shellcheck disable=SC2002
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
echo "zlib-${ZLIB_VERSION}: configure..."
./configure --static --prefix="$HOME"/staticdeps > /dev/null
echo "zlib-${ZLIB_VERSION}: make..."
make -s -j4
echo "zlib-${ZLIB_VERSION}: make install..."
make -s install
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
# Download musl tarball and signature
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
# Import musl GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
# Verify GPG signature
echo "Verifying musl GPG signature..."
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
cd "/tmp/dep_musl-${MUSL_VERSION}"
# shellcheck disable=SC2002
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
echo "musl-${MUSL_VERSION}: configure..."
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
echo "musl-${MUSL_VERSION}: make..."
make -s -j4
echo "musl-${MUSL_VERSION}: make install..."
make -s install
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true -Dpkl.musl=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-alpine-linux-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-alpine-linux-amd64-release
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-alpine-linux-amd64-release
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-cli-windows-amd64-release:
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-cli:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-cli-windows-amd64
path: pkl-cli*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-cli-windows-amd64-release
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-cli-windows-amd64-release
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-macOS-amd64-release:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true -Dpkl.targetArch=amd64 -Dpkl.native--native-compiler-path=${{ github.workspace }}/.github/scripts/cc_macos_amd64.sh pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-macOS-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-macOS-amd64-release
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-macOS-amd64-release
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-linux-amd64-release:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-linux-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-linux-amd64-release
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-linux-amd64-release
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-doc-macOS-aarch64-release:
if: github.repository_owner == 'apple'
runs-on:
- self-hosted
- macos
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-macOS-aarch64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-macOS-aarch64-release
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-macOS-aarch64-release
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-linux-aarch64-release:
runs-on: ubuntu-24.04-arm
env:
LANG: en_US.UTF-8
steps:
- name: Install deps
run: dnf install -y git binutils gcc glibc-devel zlib-devel libstdc++-static glibc-langpack-en
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: aarch64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Fix git ownership
run: git status || git config --system --add safe.directory $GITHUB_WORKSPACE
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-linux-aarch64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-linux-aarch64-release
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-linux-aarch64-release
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
container:
image: redhat/ubi8:8.10
pkl-doc-alpine-linux-amd64-release:
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: Install musl and zlib
run: |
set -e
mkdir -p ~/staticdeps/
ZLIB_VERSION="1.2.13"
MUSL_VERSION="1.2.5"
# install zlib
if [[ ! -f ~/staticdeps/include/zlib.h ]]; then
# Download zlib tarball and signature
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz" -o /tmp/zlib.tar.gz
curl -Lf "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz.asc" -o /tmp/zlib.tar.gz.asc
# Import zlib GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 5ED46A6721D365587791E2AA783FCD8E58BCAFBA
# Verify GPG signature
echo "Verifying zlib GPG signature..."
gpg --verify /tmp/zlib.tar.gz.asc /tmp/zlib.tar.gz
mkdir -p "/tmp/dep_zlib-${ZLIB_VERSION}"
cd "/tmp/dep_zlib-${ZLIB_VERSION}"
# shellcheck disable=SC2002
cat /tmp/zlib.tar.gz | tar --strip-components=1 -xzC .
echo "zlib-${ZLIB_VERSION}: configure..."
./configure --static --prefix="$HOME"/staticdeps > /dev/null
echo "zlib-${ZLIB_VERSION}: make..."
make -s -j4
echo "zlib-${ZLIB_VERSION}: make install..."
make -s install
rm -rf /tmp/dep_zlib-${ZLIB_VERSION}
fi
# install musl
if [[ ! -f ~/staticdeps/bin/x86_64-linux-musl-gcc ]]; then
# Download musl tarball and signature
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz" -o /tmp/musl.tar.gz
curl -Lf "https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz.asc" -o /tmp/musl.tar.gz.asc
# Import musl GPG key
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 836489290BB6B70F99FFDA0556BCDB593020450F
# Verify GPG signature
echo "Verifying musl GPG signature..."
gpg --verify /tmp/musl.tar.gz.asc /tmp/musl.tar.gz
mkdir -p "/tmp/dep_musl-${MUSL_VERSION}"
cd "/tmp/dep_musl-${MUSL_VERSION}"
# shellcheck disable=SC2002
cat /tmp/musl.tar.gz | tar --strip-components=1 -xzC .
echo "musl-${MUSL_VERSION}: configure..."
./configure --disable-shared --prefix="$HOME"/staticdeps > /dev/null
echo "musl-${MUSL_VERSION}: make..."
make -s -j4
echo "musl-${MUSL_VERSION}: make install..."
make -s install
rm -rf "/tmp/dep_musl-${MUSL_VERSION}"
# native-image expects to find an executable at this path.
ln -s ~/staticdeps/bin/musl-gcc ~/staticdeps/bin/x86_64-linux-musl-gcc
fi
echo "${HOME}/staticdeps/bin" >> "$GITHUB_PATH"
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true -Dpkl.musl=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-alpine-linux-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-alpine-linux-amd64-release
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-alpine-linux-amd64-release
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
pkl-doc-windows-amd64-release:
runs-on: windows-latest
env:
LANG: en_US.UTF-8
JAVA_HOME: /jdk
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- name: gradle buildNative
shell: bash
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true pkl-doc:buildNative
- name: Upload executable artifacts
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: executable-pkl-doc-windows-amd64
path: pkl-doc*/build/executable/**/*
- name: Upload Test Result XML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-xml-pkl-doc-windows-amd64-release
path: '**/build/test-results/**/*.xml'
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-pkl-doc-windows-amd64-release
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
deploy-release:
needs:
- gradle-check
- gradle-check-windows
- bench
- gradle-compatibility
- java-executables-release
- pkl-cli-macOS-amd64-release
- pkl-cli-linux-amd64-release
- pkl-cli-macOS-aarch64-release
- pkl-cli-linux-aarch64-release
- pkl-cli-alpine-linux-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-alpine-linux-amd64-release
- pkl-doc-windows-amd64-release
runs-on: ubuntu-latest
env:
LANG: en_US.UTF-8
environment: maven-release
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
java-version: '21'
distribution: temurin
architecture: x64
- uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
with: {}
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
pattern: executable-**
merge-multiple: true
- env:
ORG_GRADLE_PROJECT_signingKeyId: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGKEYID }}
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGKEY }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGPASSWORD }}
ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPEPASSWORD }}
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPEUSERNAME }}
run: ./gradlew --info --stacktrace --no-daemon -DpklMultiJdkTesting=true -DreleaseBuild=true publishToSonatype closeAndReleaseSonatypeStagingRepository
github-release:
needs: deploy-release
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
pattern: executable-**
merge-multiple: true
- name: Publish release on GitHub
env:
GH_TOKEN: ${{ github.token }}
TAG_NAME: ${{ github.ref_name }}
GIT_SHA: ${{ github.sha }}
GH_REPO: ${{ github.repository }}
run: |-
# exclude build_artifacts.txt from publish
rm -f */build/executable/*.build_artifacts.txt
find */build/executable/* -type d | xargs rm -rf
gh release create ${TAG_NAME} \
--title "${TAG_NAME}" \
--target "${GIT_SHA}" \
--verify-tag \
--notes "Release notes: https://pkl-lang.org/main/current/release-notes/changelog.html#release-${TAG_NAME}" \
*/build/executable/*
publish-test-results:
if: '!cancelled()'
needs:
- gradle-check
- gradle-check-windows
- gradle-compatibility
- java-executables-release
- pkl-cli-macOS-amd64-release
- pkl-cli-linux-amd64-release
- pkl-cli-macOS-aarch64-release
- pkl-cli-linux-aarch64-release
- pkl-cli-alpine-linux-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-alpine-linux-amd64-release
- pkl-doc-windows-amd64-release
permissions:
checks: write
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
pattern: test-results-xml-*
- name: Publish test results
if: '!cancelled()'
uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2
with:
comment_mode: 'off'
files: test-results-xml-*/**/*.xml
- name: Upload Test Result HTML
if: '!cancelled()'
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
with:
name: test-results-html-publish-test-results
path: '**/build/reports/tests/**/*'
if-no-files-found: ignore
trigger-downstream-builds:
if: github.repository_owner == 'apple'
needs:
- gradle-check
- gradle-check-windows
- bench
- gradle-compatibility
- java-executables-release
- pkl-cli-macOS-amd64-release
- pkl-cli-linux-amd64-release
- pkl-cli-macOS-aarch64-release
- pkl-cli-linux-aarch64-release
- pkl-cli-alpine-linux-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-alpine-linux-amd64-release
- pkl-doc-windows-amd64-release
- deploy-release
- github-release
- publish-test-results
runs-on: ubuntu-latest
steps:
- name: Create app token
id: app-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2
with:
app-id: ${{ secrets.PKL_CI_CLIENT_ID }}
private-key: ${{ secrets.PKL_CI }}
owner: ${{ github.repository_owner }}
- name: Trigger pkl-lang.org build
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |-
gh workflow run \
--repo apple/pkl-lang.org \
--ref main \
--field source_run="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
main.yml

34
.github/workflows/test_report.yml generated vendored Normal file
View File

@@ -0,0 +1,34 @@
# Generated from Workflow.pkl. DO NOT EDIT.
name: PR Test Reports
'on':
workflow_run:
types:
- completed
workflows:
- Pull Request
permissions:
contents: read
jobs:
test-results:
name: Test Results
if: github.event.workflow_run.conclusion == 'success' || github.event.workflow_run.conclusion == 'failure'
permissions:
actions: read
checks: write
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11
with:
path: artifacts
name: test-results-.*
name_is_regexp: true
run_id: ${{ github.event.workflow_run.id }}
- name: Publish test results
uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2
with:
commit: ${{ github.event.workflow_run.head_sha }}
comment_mode: 'off'
files: artifacts/**/*.xml
event_file: artifacts/test-results-event-file/event.json
event_name: ${{ github.event.workflow_run.event }}

10
.gitignore vendored
View File

@@ -5,6 +5,7 @@
.gradle/
build/
generated/
testgenerated/
# IntelliJ
.idea/
@@ -14,7 +15,10 @@ generated/
!.idea/runConfigurations/
!.idea/scopes/
!.idea/vcs.xml
.intellijPlatform/
# :pkl-core:makeIntelliJAntlrPluginHappy
gen/
PklLexer.tokens
.vscode/
.pkl-lsp/
.kotlin/

View File

@@ -63,6 +63,7 @@
</option>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="" withSubpackages="true" static="false" module="true" />
<package name="" withSubpackages="true" static="true" />
<emptyLine />
<package name="" withSubpackages="true" static="false" />

View File

@@ -74,4 +74,4 @@
<option name="processComments" value="true" />
</inspection_tool>
</profile>
</component>
</component>

View File

@@ -1 +1 @@
17.0
21

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

@@ -2,19 +2,22 @@
:uri-gng: https://gng.dsun.org
:uri-jenv: https://www.jenv.be
:uri-intellij: https://www.jetbrains.com/idea/download/
:uri-jdk: https://adoptopenjdk.net/releases.html?variant=openjdk17
:uri-native-prerequisites-linux: https://www.graalvm.org/latest/getting-started/linux/#prerequisites-for-native-image-on-linux
:uri-native-prerequisites-windows: https://www.graalvm.org/latest/getting-started/windows/#prerequisites-for-native-image-on-windows
== Setup
. (mandatory) Install {uri-jdk}[OpenJDK 17] or higher
. (recommended) Install {uri-intellij}[IntelliJ IDEA 2023.x] +
. (mandatory) Install a JDK (JDK 21+ required).
. (recommended) Install {uri-intellij}[IntelliJ IDEA] +
To import the project into IntelliJ, go to File->Open and select the project's root directory.
If the project is opened but not imported, look for a popup in the lower right corner
and click its "Import Gradle Project" link.
. (recommended) Install {uri-gng}[gng] +
_gng_ enables to run Gradle commands with `gw` (instead of `./gradlew`) from any subdirectory.
. (recommended) Set up Git ignore-revs +
`git config blame.ignoreRevsFile .git-blame-ignore-revs`
. (recommended) Install {uri-jenv}[jenv] and plugins +
_jenv_ use specific JDK versions in certain subdirectories. _Pkl_ comes with a `.java-version` file specifying JDK 17. +
_jenv_ use specific JDK versions in certain subdirectories. _Pkl_ comes with a `.java-version` file specifying JDK 21. +
Enable _jenv_ plugins for better handling by `gradle`:
+
[source,shell]
@@ -22,22 +25,35 @@ Enable _jenv_ plugins for better handling by `gradle`:
jenv enable-plugin gradle
jenv enable-plugin export
----
. (optional) If you've named the original apple/pkl git repository something other than `origin`, set env var `PKL_ORIGINAL_REMOTE_NAME` to that name in your `.bashrc`, `.zshrc`, `config.fish` or however you manage your local environment.
+
This will allow spotless to pick the correct starting branch when formatting source code files.
Otherwise, you might see that _every_ file has its copyright year updated.
=== Additional Linux Setup
. (optional) To build the native executable (`./gradlew buildNative`),
install {uri-native-prerequisites-linux}[Prerequisites For Native Image on Linux].
=== Additional Windows Setup
. (optional) Go to `System->For developers` and enable `Developer Mode`.
Otherwise, some tests may fail due to insufficient file system privileges.
. (optional) To build the native executable (`./gradlew buildNative`),
install {uri-native-prerequisites-windows}[Prerequisites For Native Image on Windows].
== Common Build Commands
[source,shell]
----
gw clean
gw test # run all tests except native executable tests
gw testNative # run native executable tests
gw spotlessApply # fix code formatting
gw build # build everything except native executables
gw buildNative # build macOS executable on macOS,
# Linux and Alpine executables on Linux
# (Alpine executable is only built if ~/staticdeps/bin/musl-gcc exists)
gw test # run all tests except native executable tests
gw spotlessApply # fix code formatting
gw build # build everything except native executables
gw pkl-cli:testNative # run native executable tests
gw pkl-cli:buildNative # build native executable for current platform
pkl-cli/build/executable/jpkl # run Java executable
pkl-cli/build/executable/pkl-macos-amd64 # run Mac executable
pkl-cli/build/executable/pkl-macos-aarch64 # run Mac executable
pkl-cli/build/executable/pkl-macos-amd64 # run Intel Mac executable
pkl-cli/build/executable/pkl-linux-amd64 # run Linux executable
pkl-cli/build/executable/pkl-alpine-linux-amd64 # run Alpine Linux executable
pkl-cli/build/executable/pkl-windows-amd64.exe # run Windows executable
@@ -66,8 +82,6 @@ based on version information from https://search.maven.org, https://plugins.grad
* Truffle code generation is performed by Truffle's annotation processor, which runs as part of task `:pkl-core:compileJava`
** Output dir is `generated/truffle/`
* ANTLR code generation is performed by task `:pkl-core:generateGrammarSource`
** Output dir is `generated/antlr/`
== Remote JVM Debugging
@@ -76,14 +90,20 @@ This will listen on port 5005.
Example: `./gradlew test -Djvmdebug=true`
== Snippet Test Plugin
There is an IntelliJ plugin meant for development on the Pkl project itself.
This plugin provides a split pane window when viewing snippet tests such as LanguageSnippetTests and FormatterSnippetTests.
To install:
1. Run `./gradlew pkl-internal-intellij-plugin:buildPlugin`.
2. Within IntelliJ, run the action "Install Plugin From Disk...".
3. Select the zip file within `pkl-internal-intellij-plugin/build/distributions`.
== Resources
For automated build setup examples see our https://github.com/apple/pkl/blob/main/.circleci/[CircleCI] jobs like our https://github.com/apple/pkl/blob/main/.circleci/jobs/BuildNativeJob.pkl[BuildNativeJob.pkl], where we build Pkl automatically.
=== ANTLR
* https://github.com/antlr/antlr4/blob/main/doc/index.md[Documentation]
* https://groups.google.com/forum/#!forum/antlr-discussion[Forums]
* https://github.com/mobileink/lab.clj.antlr/tree/main/doc[Some third-party docs]
For automated build setup examples see our https://github.com/apple/pkl/blob/main/.github/[GitHub Actions] jobs like our https://github.com/apple/pkl/blob/main/.github/jobs/BuildNativeJob.pkl[BuildNativeJob.pkl], where we build Pkl automatically.
=== Truffle

View File

@@ -8,4 +8,5 @@ See link:CONTRIBUTING.adoc[] for general contribution guidelines.
* https://github.com/bioball[Daniel Chao]
* https://github.com/stackoverflow[Islon Scherer]
* https://github.com/HT154[Jen Basch]
* https://github.com/holzensp[Philip Hölzenspies]

View File

@@ -1,4 +1,4 @@
Copyright © 2024 Apple Inc. and the Pkl project authors
Copyright © 2024-2025 Apple Inc. and the Pkl project authors
Portions of this software were originally based on 'SnakeYAML' developed by Andrey Somov.

View File

@@ -12,7 +12,7 @@
:uri-installation: https://pkl-lang.org/main/current/pkl-cli/index.html#installation
:uri-lang-reference: https://pkl-lang.org/main/current/language-reference/index.html
:uri-ci-artifacts: https://s01.oss.sonatype.org/content/groups/public/org/pkl-lang/
:uri-ci-pipeline: https://app.circleci.com/pipelines/github/apple/pkl
:uri-ci-pipeline: https://github.com/apple/pkl/actions
A configuration as code language with rich validation and tooling.
@@ -37,7 +37,86 @@ We'd love to hear from you!
* Create an {uri-github-issue}[issue]
* Ask a question on {uri-github-discussions}[GitHub Discussions]
== Development image:https://circleci.com/gh/apple/pkl.svg?style=svg["Apple", link="https://app.circleci.com/pipelines/github/apple/pkl"]
== Development
image:https://github.com/apple/pkl/actions/workflows/main.yml/badge.svg?style=svg["Build (main)", link="https://github.com/apple/pkl/actions/workflows/main.yml"]
* link:CONTRIBUTING.adoc[] for tips on pull requests and filing issues
* link:DEVELOPMENT.adoc[] for build instructions
* {uri-ci-artifacts}[Sonatype Repository] for the artifacts/binaries built by our {uri-ci-pipeline}[CI pipelines] (and those of our other tools and packages repositories).
== Pkl GitHub Repositories
[%autowidth]
|===
|Name |Description
|`apple/pkl`
|A configuration as code language with rich validation and tooling.
|https://github.com/apple/pkl-evolution[`apple/pkl-evolution`]
|Suggested Pkl Improvements, Changes, or Enhancements (SPICEs)
|https://github.com/apple/pkl-go[`apple/pkl-go`]
|Pkl bindings for the Go programming language
|https://github.com/apple/pkl-go-examples[`apple/pkl-go-examples`]
|Examples for using Pkl within Go applications
|https://github.com/apple/highlightjs-pkl[`apple/highlightjs-pkl`]
|Highlight.js syntax highlighting for Pkl
|https://github.com/apple/pkl-intellij[`apple/pkl-intellij`]
|JetBrains editor plugins providing Pkl language support
|https://github.com/apple/pkl-jvm-examples[`apple/pkl-jvm-examples`]
|Examples for using Pkl within JVM applications
|https://github.com/apple/pkl-k8s[`apple/pkl-k8s`]
|Templates for using Pkl with Kubernetes
|https://github.com/apple/pkl-k8s-examples[`apple/pkl-k8s-examples`]
|Examples for using Pkl with Kubernetes
|https://github.com/apple/pkl-lang.org[`apple/pkl-lang.org`]
|The pkl-lang.org website
|https://github.com/apple/pkl-lsp[`apple/pkl-lsp`]
|Language server for Pkl, implementing the server-side of the Language Server Protocol
|https://github.com/apple/pkl-neovim[`apple/pkl-neovim`]
|Pkl language support for Neovim
|https://github.com/apple/pkl-package-docs[`apple/pkl-package-docs`]
|Documentation for Pkl packages
|https://github.com/apple/pkl-pantry[`apple/pkl-pantry`]
|Shared Pkl packages
|https://github.com/apple/pkl-project-commons[`apple/pkl-project-commons`]
|Utility libraries for Pkl
|https://github.com/apple/pkl-readers[`apple/pkl-readers`]
|Shared Pkl https://pkl-lang.org/main/current/language-reference/index.html#external-readers[external reader] tools
|https://github.com/apple/pkl-spring[`apple/pkl-spring`]
|Spring Boot extension for configuring Boot apps with Pkl
|https://github.com/apple/pkl-swift[`apple/pkl-swift`]
|Pkl bindings for the Swift programming language
|https://github.com/apple/pkl-swift-examples[`apple/pkl-swift-examples`]
|Examples for using Pkl within Swift applications
|https://github.com/apple/pkl-vscode[`apple/pkl-vscode`]
|Pkl language support for VS Code
|https://github.com/apple/pkl.tmbundle[`apple/pkl.tmbundle`]
|TextMate bundle for Pkl
|https://github.com/apple/tree-sitter-pkl[`apple/tree-sitter-pkl`]
|Tree-sitter parser for Pkl
|https://github.com/apple/rules_pkl[`apple/rules_pkl`]
|Bazel build rules for Pkl
|===

View File

@@ -26,18 +26,7 @@ Copyright © 2017 Square, Inc.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
4) ANTLR 4 Runtime (Optimized) (http://tunnelvisionlabs.com)
POM License: The BSD License - http://www.antlr.org/license.html
Copyright (c) 2012 Terence Parr and Sam Harwell
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5) GeantyRef (https://github.com/leangen/geantyref)
4) GeantyRef (https://github.com/leangen/geantyref)
Manifest license URL: https://www.apache.org/licenses/LICENSE-2.0
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
@@ -47,7 +36,7 @@ Copyright © 2017 Kaqqao
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
6) commonmark-java core
5) commonmark-java core
POM License: The 2-Clause BSD License - https://opensource.org/licenses/BSD-2-Clause
Embedded license:
@@ -78,7 +67,7 @@ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7) commonmark-java extension for tables
6) commonmark-java extension for tables
POM License: The 2-Clause BSD License - https://opensource.org/licenses/BSD-2-Clause
Embedded license:
@@ -109,7 +98,7 @@ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8) jansi (http://fusesource.com/)
7) jansi (http://fusesource.com/)
Manifest license URL: https://www.apache.org/licenses/LICENSE-2.0
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
@@ -119,13 +108,13 @@ Copyright © Fusesource 2023
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
9) Graal Sdk (https://github.com/oracle/graal)
8) Graal Sdk (https://github.com/oracle/graal)
POM License: Universal Permissive License, Version 1.0 - http://opensource.org/licenses/UPL
10) Truffle API (http://openjdk.java.net/projects/graal)
9) Truffle API (http://openjdk.java.net/projects/graal)
POM License: Universal Permissive License, Version 1.0 - http://opensource.org/licenses/UPL
11) IntelliJ IDEA Annotations (http://www.jetbrains.org)
10) IntelliJ IDEA Annotations (http://www.jetbrains.org)
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
The Apache License
@@ -133,7 +122,7 @@ Copyright © Jetbrains 2023
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
12) kotlin-reflect (https://kotlinlang.org/)
11) kotlin-reflect (https://kotlinlang.org/)
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
The Apache License
@@ -141,7 +130,7 @@ Copyright © Wuseal 2018
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
13) kotlin-stdlib (https://kotlinlang.org/)
12) kotlin-stdlib (https://kotlinlang.org/)
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
The Apache License
@@ -149,7 +138,7 @@ Copyright © 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contribu
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
14) kotlin-stdlib-common (https://kotlinlang.org/)
13) kotlin-stdlib-common (https://kotlinlang.org/)
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
The Apache License
@@ -157,7 +146,7 @@ Copyright © 2023 Kotlin Team
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
15) kotlin-stdlib-jdk7 (https://kotlinlang.org/)
14) kotlin-stdlib-jdk7 (https://kotlinlang.org/)
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
The Apache License
@@ -165,7 +154,7 @@ Copyright © 2023 Kotlin Team
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
16) kotlin-stdlib-jdk8 (https://kotlinlang.org/)
15) kotlin-stdlib-jdk8 (https://kotlinlang.org/)
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
The Apache License
@@ -173,7 +162,7 @@ Copyright © 2023 Kotlin Team
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
17) kotlinx.html (https://github.com/Kotlin/kotlinx.html)
16) kotlinx.html (https://github.com/Kotlin/kotlinx.html)
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
The Apache License
@@ -181,7 +170,7 @@ Copyright © 2017 Yole
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
18) kotlinx-serialization-core (https://github.com/Kotlin/kotlinx.serialization)
17) kotlinx-serialization-core (https://github.com/Kotlin/kotlinx.serialization)
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
The Apache License
@@ -189,7 +178,7 @@ The Apache License
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
19) kotlinx-serialization-json (https://github.com/Kotlin/kotlinx.serialization)
18) kotlinx-serialization-json (https://github.com/Kotlin/kotlinx.serialization)
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
The Apache License
@@ -197,7 +186,7 @@ The Apache License
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
20) JLine Reader
19) JLine Reader
Manifest license URL: https://opensource.org/licenses/BSD-3-Clause
POM License: The 3-Clause BSD License - https://opensource.org/licenses/BSD-3-Clause
@@ -216,7 +205,7 @@ software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21) JLine Terminal
20) JLine Terminal
Manifest license URL: https://opensource.org/licenses/BSD-3-Clause
POM License: The 3-Clause BSD License - https://opensource.org/licenses/BSD-3-Clause
@@ -235,7 +224,7 @@ software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22) JLine JANSI Terminal
21) JLine JANSI Terminal
Manifest license URL: https://opensource.org/licenses/BSD-3-Clause
POM License: The 3-Clause BSD License - https://opensource.org/licenses/BSD-3-Clause
@@ -254,7 +243,7 @@ software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23) msgpack-core (https://msgpack.org/)
22) msgpack-core (https://msgpack.org/)
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
The Apache License
@@ -262,7 +251,7 @@ Copyright © 2016 Sadayuki Furuhashi, Muga Nishizawa, Taro L. Saito, Mitsunori K
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
24) Paguro (https://github.com/GlenKPeterson/Paguro)
23) Paguro (https://github.com/GlenKPeterson/Paguro)
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
The Apache License
@@ -364,7 +353,7 @@ Everyone is permitted to copy and distribute copies of this Agreement, but in or
This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
25) SnakeYAML Engine (http://www.snakeyaml.org)
24) SnakeYAML Engine (http://www.snakeyaml.org)
Manifest license URL: https://www.apache.org/licenses/LICENSE-2.0
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0

View File

@@ -1,31 +1,45 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
plugins {
pklAllProjects
pklJavaLibrary
pklGraalVm
id("me.champeau.jmh")
}
val truffle: Configuration by configurations.creating
val graal: Configuration by configurations.creating
@Suppress("UnstableApiUsage")
dependencies {
jmh(projects.pklCore)
// necessary because antlr4-runtime is declared as implementation dependency in pkl-core.gradle
jmh(libs.antlrRuntime)
jmh(projects.pklCommonsTest)
jmh(projects.pklParser)
truffle(libs.truffleApi)
graal(libs.graalCompiler)
}
jmh {
//include = ["fib_class_java"]
//include = ["fib_class_constrained1", "fib_class_constrained2"]
// include = ["fib_class_java"]
// include = ["fib_class_constrained1", "fib_class_constrained2"]
jmhVersion.set(libs.versions.jmh)
// jvmArgsAppend = "-Dgraal.TruffleCompilationExceptionsAreFatal=true " +
// "-Dgraal.Dump=Truffle,TruffleTree -Dgraal.TraceTruffleCompilation=true " +
// "-Dgraal.TruffleFunctionInlining=false"
jvm.set("${buildInfo.graalVmAmd64.baseDir}/bin/java")
// see: https://docs.oracle.com/en/graalvm/enterprise/20/docs/graalvm-as-a-platform/implement-language/#disable-class-path-separation
// see:
// https://docs.oracle.com/en/graalvm/enterprise/20/docs/graalvm-as-a-platform/implement-language/#disable-class-path-separation
jvmArgs.set(
listOf(
// one JVM arg per list element doesn't work, but the following does
@@ -33,16 +47,13 @@ jmh {
)
)
includeTests.set(false)
//threads = Runtime.runtime.availableProcessors() / 2 + 1
//synchronizeIterations = false
// threads = Runtime.runtime.availableProcessors() / 2 + 1
// synchronizeIterations = false
}
tasks.named("jmh") {
dependsOn(":installGraalVmAmd64")
}
tasks.named("jmh") { dependsOn(":installGraalVmAmd64") }
// Prevent this error which occurs when building in IntelliJ:
// "Entry org/pkl/core/fib_class_typed.pkl is a duplicate but no duplicate handling strategy has been set."
tasks.processJmhResources {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
// "Entry org/pkl/core/fib_class_typed.pkl is a duplicate but no duplicate handling strategy has
// been set."
tasks.processJmhResources { duplicatesStrategy = DuplicatesStrategy.EXCLUDE }

View File

@@ -1,43 +1,69 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.tunnelvisionlabs:antlr4-runtime:4.9.0=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
net.bytebuddy:byte-buddy:1.14.16=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
com.github.ben-manes.caffeine:caffeine:2.9.3=swiftExportClasspathResolvable
com.google.errorprone:error_prone_annotations:2.28.0=swiftExportClasspathResolvable
io.github.java-diff-utils:java-diff-utils:4.12=kotlinInternalAbiValidation
io.opentelemetry:opentelemetry-api:1.41.0=swiftExportClasspathResolvable
io.opentelemetry:opentelemetry-context:1.41.0=swiftExportClasspathResolvable
net.bytebuddy:byte-buddy:1.17.7=jmh,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
net.sf.jopt-simple:jopt-simple:5.0.4=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
org.apache.commons:commons-math3:3.6.1=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
org.assertj:assertj-core:3.26.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.graalvm.compiler:compiler:23.0.2=graal
org.graalvm.sdk:graal-sdk:23.0.2=graal,jmh,jmhRuntimeClasspath,truffle
org.graalvm.truffle:truffle-api:23.0.2=graal,jmh,jmhRuntimeClasspath,truffle
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.7.10=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-reflect:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-script-runtime:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains:annotations:13.0=kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-api:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-engine:5.10.2=testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-params:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.platform:junit-platform-commons:1.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.platform:junit-platform-engine:1.10.2=testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit:junit-bom:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.apiguardian:apiguardian-api:1.1.2=jmhCompileClasspath,jmhImplementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata
org.assertj:assertj-core:3.27.6=jmh,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.bouncycastle:bcpg-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.bouncycastle:bcpkix-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.bouncycastle:bcprov-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.bouncycastle:bcutil-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.checkerframework:checker-qual:3.43.0=swiftExportClasspathResolvable
org.graalvm.compiler:compiler:25.0.0=graal
org.graalvm.polyglot:polyglot:25.0.0=jmh,jmhRuntimeClasspath,truffle
org.graalvm.sdk:collections:25.0.0=graal,jmh,jmhRuntimeClasspath,truffle
org.graalvm.sdk:graal-sdk:25.0.0=jmh,jmhRuntimeClasspath
org.graalvm.sdk:nativeimage:25.0.0=jmh,jmhRuntimeClasspath,truffle
org.graalvm.sdk:word:25.0.0=graal,jmh,jmhRuntimeClasspath,truffle
org.graalvm.truffle:truffle-api:25.0.0=jmh,jmhRuntimeClasspath,truffle
org.graalvm.truffle:truffle-compiler:25.0.0=graal
org.jetbrains.kotlin:abi-tools-api:2.2.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:abi-tools:2.2.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:kotlin-build-tools-api:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-compiler-runner:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:2.2.20=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-metadata-jvm:2.2.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:kotlin-native-prebuilt:2.0.21=kotlinNativeBundleConfiguration
org.jetbrains.kotlin:kotlin-reflect:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-script-runtime:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-scripting-common:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-jvm:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.20=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.20=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:2.2.20=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:swift-export-embeddable:2.2.20=swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.3=swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.3=swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3=swiftExportClasspathResolvable
org.jetbrains:annotations:13.0=jmh,jmhCompileClasspath,jmhRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathJmh,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable,testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-api:5.14.0=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:5.14.0=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.14.0=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.platform:junit-platform-commons:1.14.0=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.platform:junit-platform-engine:1.14.0=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-launcher:1.14.0=testRuntimeClasspath
org.junit:junit-bom:5.14.0=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.msgpack:msgpack-core:0.9.8=jmh,jmhRuntimeClasspath
org.openjdk.jmh:jmh-core:1.37=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
org.openjdk.jmh:jmh-generator-asm:1.37=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
org.openjdk.jmh:jmh-generator-bytecode:1.37=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
org.openjdk.jmh:jmh-generator-reflection:1.37=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.opentest4j:opentest4j:1.3.0=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.organicdesign:Paguro:3.10.3=jmh,jmhRuntimeClasspath
org.ow2.asm:asm:9.0=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
org.snakeyaml:snakeyaml-engine:2.5=jmh,jmhRuntimeClasspath
empty=annotationProcessor,apiDependenciesMetadata,archives,compile,compileClasspath,compileOnly,compileOnlyDependenciesMetadata,default,implementationDependenciesMetadata,intransitiveDependenciesMetadata,jmhAnnotationProcessor,jmhApiDependenciesMetadata,jmhCompile,jmhCompileOnly,jmhCompileOnlyDependenciesMetadata,jmhIntransitiveDependenciesMetadata,jmhKotlinScriptDef,jmhKotlinScriptDefExtensions,jmhRuntime,jmhRuntimeOnlyDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtime,runtimeClasspath,runtimeOnlyDependenciesMetadata,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompile,testCompileOnly,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDef,testKotlinScriptDefExtensions,testRuntime
org.snakeyaml:snakeyaml-engine:2.10=jmh,jmhRuntimeClasspath
empty=annotationProcessor,apiDependenciesMetadata,compileClasspath,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,jmhAnnotationProcessor,jmhApiDependenciesMetadata,jmhCompileOnlyDependenciesMetadata,jmhIntransitiveDependenciesMetadata,jmhKotlinScriptDefExtensions,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,runtimeClasspath,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions

View File

@@ -1,4 +1,4 @@
/**
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");

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.
@@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.util.TempFile;
import org.openjdk.jmh.util.TempFileManager;
import org.pkl.core.evaluatorSettings.TraceMode;
import org.pkl.core.http.HttpClient;
import org.pkl.core.module.ModuleKeyFactories;
import org.pkl.core.repl.ReplRequest;
@@ -50,7 +51,9 @@ public class ListSort {
null,
null,
IoUtils.getCurrentWorkingDir(),
StackFrameTransformers.defaultTransformer);
StackFrameTransformers.defaultTransformer,
false,
TraceMode.COMPACT);
private static final List<Object> list = new ArrayList<>(100000);
static {

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.
@@ -15,8 +15,17 @@
*/
package org.pkl.core.parser;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.*;
import org.pkl.commons.test.FileTestUtils;
import org.pkl.commons.test.FileTestUtilsKt;
import org.pkl.core.Release;
import org.pkl.core.util.IoUtils;
import org.pkl.parser.Parser;
import org.pkl.parser.ParserError;
@SuppressWarnings("unused")
@Warmup(iterations = 5, time = 2)
@@ -24,37 +33,33 @@ import org.openjdk.jmh.annotations.*;
@OutputTimeUnit(TimeUnit.SECONDS)
@Fork(1)
public class ParserBenchmark {
// One-time execution of this code took ~10s until moving rule alternative
// for parenthesized expression after alternative for anonymous function.
@Benchmark
public void run() {
new Parser()
.parseModule(
"""
a1 {
a2 {
a3 {
a4 {
a5 {
a6 {
a7 {
a8 {
a9 {
a10 {
a11 {
a12 {
a13 = map(map(map((x) -> 1)))
}
}
}
}
}
}
}
}
}
}
}
}""");
public void parseStdlib() {
for (var stdlibModule : Release.current().standardLibrary().modules()) {
try {
var moduleSource =
IoUtils.readClassPathResourceAsString(
getClass(), "/org/pkl/core/stdlib/%s.pkl".formatted(stdlibModule.substring(4)));
new Parser().parseModule(moduleSource);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
@Benchmark
public void parseSnippetTests() {
var snippetTestDir =
FileTestUtils.getRootProjectDir()
.resolve("pkl-core/src/test/files/LanguageSnippetTests/input");
for (var snippet : FileTestUtilsKt.listFilesRecursively(snippetTestDir)) {
try {
var moduleSource = Files.readString(snippet);
new Parser().parseModule(moduleSource);
} catch (IOException e) {
throw new UncheckedIOException(e);
} catch (ParserError ignore) {
}
}
}
}

View File

@@ -1,10 +1,22 @@
/*
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// https://youtrack.jetbrains.com/issue/KTIJ-19369
@file:Suppress("DSL_SCOPE_VIOLATION")
import org.jetbrains.gradle.ext.ActionDelegationConfig
import org.jetbrains.gradle.ext.ActionDelegationConfig.TestRunner.PLATFORM
import org.jetbrains.gradle.ext.ProjectSettings
import org.jetbrains.gradle.ext.TaskTriggersConfig
plugins {
pklAllProjects
@@ -18,8 +30,8 @@ plugins {
nexusPublishing {
repositories {
sonatype {
nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/"))
snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/"))
nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/"))
snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/"))
}
}
}
@@ -33,22 +45,16 @@ idea {
delegateBuildRunToGradle = true
testRunner = PLATFORM
}
configure<TaskTriggersConfig> {
afterSync(provider { project(":pkl-core").tasks.named("makeIntelliJAntlrPluginHappy") })
}
}
}
}
val clean by tasks.registering(Delete::class) {
delete(layout.buildDirectory)
}
val clean by tasks.existing { delete(layout.buildDirectory) }
val printVersion by tasks.registering {
doFirst { println(buildInfo.pklVersion) }
}
val printVersion by tasks.registering { doFirst { println(buildInfo.pklVersion) } }
val message = """
val message =
"""
====
Gradle version : ${gradle.gradleVersion}
Java version : ${System.getProperty("java.version")}
@@ -63,5 +69,7 @@ Git Commit ID : ${buildInfo.commitId}
====
"""
val formattedMessage = message.replace("\n====", "\n" + "=".repeat(message.lines().maxByOrNull { it.length }!!.length))
val formattedMessage =
message.replace("\n====", "\n" + "=".repeat(message.lines().maxByOrNull { it.length }!!.length))
logger.info(formattedMessage)

View File

@@ -1,15 +1,32 @@
import org.jetbrains.kotlin.config.JvmTarget
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
`kotlin-dsl`
`jvm-toolchains`
}
// Keep this in sync with the constants in `BuildInfo.kt` (those are not addressable here).
val toolchainVersion = 21
dependencies {
implementation(libs.downloadTaskPlugin)
implementation(libs.spotlessPlugin)
implementation(libs.kotlinPlugin) {
exclude(module = "kotlin-android-extensions")
}
implementation(libs.kotlinPlugin) { exclude(module = "kotlin-android-extensions") }
implementation(libs.shadowPlugin)
// fix from the Gradle team: makes version catalog symbols available in build scripts
@@ -18,16 +35,18 @@ dependencies {
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlin {
target {
compilations.configureEach {
kotlinOptions {
jvmTarget = "17"
}
}
toolchain {
languageVersion = JavaLanguageVersion.of(toolchainVersion)
vendor = JvmVendorSpec.ADOPTIUM
}
}
tasks.withType<JavaCompile>().configureEach { options.release = toolchainVersion }
kotlin {
jvmToolchain(toolchainVersion)
compilerOptions {
jvmTarget = JvmTarget.fromTarget(toolchainVersion.toString())
freeCompilerArgs.add("-Xjdk-release=$toolchainVersion")
}
}

View File

@@ -1,3 +1,18 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:Suppress("UnstableApiUsage")
rootProject.name = "buildSrc"
@@ -9,14 +24,12 @@ pluginManagement {
}
}
plugins { id("org.gradle.toolchains.foojay-resolver-convention") }
// makes ~/.gradle/init.gradle unnecessary and ~/.gradle/gradle.properties optional
dependencyResolutionManagement {
// use same version catalog as main build
versionCatalogs {
register("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
versionCatalogs { register("libs") { from(files("../gradle/libs.versions.toml")) } }
repositories {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)

View File

@@ -1,26 +1,79 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:Suppress("MemberVisibilityCanBePrivate")
import java.io.File
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.kotlin.dsl.getByType
import org.gradle.api.attributes.Category
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.testing.Test
import org.gradle.internal.extensions.stdlib.capitalized
import org.gradle.jvm.toolchain.*
import org.gradle.kotlin.dsl.*
import org.gradle.kotlin.dsl.support.serviceOf
import org.gradle.process.CommandLineArgumentProvider
/**
* JVM bytecode target; this is pinned at a reasonable version, because downstream JVM projects
* which consume Pkl will need a minimum Bytecode level at or above this one.
*
* Kotlin and Java need matching bytecode targets, so this is expressed as a build setting and
* constant default. To override, pass `-DpklJdkToolchain=X` to the Gradle command line, where X is
* a major Java version.
*/
const val PKL_JVM_TARGET_DEFAULT_MAXIMUM = 17
/**
* The Pkl build requires JDK 21+ to build, because JDK 17 is no longer within the default set of
* supported JDKs for GraalVM. This is a build-time requirement, not a runtime requirement.
*/
const val PKL_JDK_VERSION_MIN = 21
/**
* The JDK minimum is set to match the bytecode minimum, to guarantee that fat JARs work against the
* earliest supported bytecode target.
*/
const val PKL_TEST_JDK_MINIMUM = PKL_JVM_TARGET_DEFAULT_MAXIMUM
/**
* Maximum JDK version which Pkl is tested with; this should be bumped when new JDK stable releases
* are issued. At the time of this writing, JDK 23 is the latest available release.
*/
const val PKL_TEST_JDK_MAXIMUM = 23
/**
* Test the full suite of JDKs between [PKL_TEST_JDK_MINIMUM] and [PKL_TEST_JDK_MAXIMUM]; if this is
* set to `false` (or overridden on the command line), only LTS releases are tested by default.
*/
const val PKL_TEST_ALL_JDKS = false
// `buildInfo` in main build scripts
// `project.extensions.getByType<BuildInfo>()` in precompiled script plugins
open class BuildInfo(project: Project) {
open class BuildInfo(private val project: Project) {
inner class GraalVm(val arch: String) {
val homeDir: String by lazy {
System.getenv("GRAALVM_HOME") ?: "${System.getProperty("user.home")}/.graalvm"
}
val version: String by lazy {
libs.findVersion("graalVm").get().toString()
}
val version: String by lazy { libs.findVersion("graalVm").get().toString() }
val graalVmJdkVersion: String by lazy {
libs.findVersion("graalVmJdkVersion").get().toString()
}
val graalVmJdkVersion: String by lazy { libs.findVersion("graalVmJdkVersion").get().toString() }
val osName: String by lazy {
when {
@@ -32,27 +85,39 @@ open class BuildInfo(project: Project) {
}
val baseName: String by lazy {
"graalvm-jdk-${graalVmJdkVersion}_${osName}-${arch}_bin"
"graalvm-community-jdk-${graalVmJdkVersion}_${osName}-${arch}_bin"
}
val downloadUrl: String by lazy {
val jdkMajor = graalVmJdkVersion.takeWhile { it != '.' }
val extension = if (os.isWindows) "zip" else "tar.gz"
"https://download.oracle.com/graalvm/$jdkMajor/archive/$baseName.$extension"
"https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-${graalVmJdkVersion}/$baseName.$extension"
}
val installDir: File by lazy {
File(homeDir, baseName)
val downloadFile: File by lazy {
val extension = if (os.isWindows) "zip" else "tar.gz"
File(homeDir, "${baseName}.$extension")
}
val installDir: File by lazy { File(homeDir, baseName) }
val baseDir: String by lazy {
if (os.isMacOsX) "$installDir/Contents/Home" else installDir.toString()
}
}
/**
* Same logic as [org.gradle.internal.os.OperatingSystem#arch], which is protected.
*/
/** The target architecture to build, defaulting to the system architecture. */
val targetArch by lazy { System.getProperty("pkl.targetArch") ?: arch }
/** Tells if this is a cross-arch build (e.g. targeting amd64 when on an aarch64 machine). */
val isCrossArch by lazy { arch != targetArch }
/** Tells if cross-arch builds are supported on this machine. */
val isCrossArchSupported by lazy { os.isMacOsX }
/** Whether to build native executables using the musl toolchain or not. */
val musl: Boolean by lazy { java.lang.Boolean.getBoolean("pkl.musl") }
/** Same logic as [org.gradle.internal.os.OperatingSystem#arch], which is protected. */
val arch: String by lazy {
when (val arch = System.getProperty("os.arch")) {
"x86" -> "i386"
@@ -66,16 +131,231 @@ open class BuildInfo(project: Project) {
val graalVmAmd64: GraalVm = GraalVm("x64")
val isCiBuild: Boolean by lazy {
System.getenv("CI") != null
val isCiBuild: Boolean by lazy { System.getenv("CI") != null }
val isReleaseBuild: Boolean by lazy { java.lang.Boolean.getBoolean("releaseBuild") }
val isNativeArch: Boolean by lazy { java.lang.Boolean.getBoolean("nativeArch") }
val jvmTarget: Int by lazy {
System.getProperty("pklJvmTarget")?.toInt() ?: PKL_JVM_TARGET_DEFAULT_MAXIMUM
}
val isReleaseBuild: Boolean by lazy {
java.lang.Boolean.getBoolean("releaseBuild")
// JPMS exports for Truffle; needed on some versions of Java, and transitively within some JARs.
private val jpmsExports =
arrayOf(
"org.graalvm.truffle/com.oracle.truffle.api.exception=ALL-UNNAMED",
"org.graalvm.truffle/com.oracle.truffle.api=ALL-UNNAMED",
"org.graalvm.truffle/com.oracle.truffle.api.nodes=ALL-UNNAMED",
"org.graalvm.truffle/com.oracle.truffle.api.source=ALL-UNNAMED",
)
// Extra JPMS modules forced onto the module path via `--add-modules` in some cases.
private val jpmsAddModules = arrayOf("jdk.unsupported")
// Formats `jpmsExports` for use in JAR manifest attributes.
val jpmsExportsForJarManifest: String by lazy {
jpmsExports.joinToString(" ") { it.substringBefore("=") }
}
// Formats `jpmsExports` for use on the command line with `--add-exports`.
val jpmsExportsForAddExportsFlags: Collection<String> by lazy {
jpmsExports.map { "--add-exports=$it" }
}
// Formats `jpmsAddModules` for use on the command line with `--add-modules`.
val jpmsAddModulesFlags: Collection<String> by lazy { jpmsAddModules.map { "--add-modules=$it" } }
// JVM properties to set during testing.
val testProperties =
mapOf<String, Any>(
// @TODO: this should be removed once pkl supports JPMS as a true Java Module.
"polyglotimpl.DisableClassPathIsolation" to true
)
val jdkVendor: JvmVendorSpec = JvmVendorSpec.ADOPTIUM
val jdkToolchainVersion: JavaLanguageVersion by lazy {
JavaLanguageVersion.of(System.getProperty("pklJdkToolchain")?.toInt() ?: PKL_JDK_VERSION_MIN)
}
val jdkTestFloor: JavaLanguageVersion by lazy { JavaLanguageVersion.of(PKL_TEST_JDK_MINIMUM) }
val jdkTestCeiling: JavaLanguageVersion by lazy { JavaLanguageVersion.of(PKL_TEST_JDK_MAXIMUM) }
val testAllJdks: Boolean by lazy {
// By default, Pkl is tested against LTS JDK releases within the bounds of `PKL_TEST_JDK_TARGET`
// and `PKL_TEST_JDK_MAXIMUM`. To test against the full suite of JDK versions, past and present,
// set `-DpklTestAllJdks=true` on the Gradle command line. This results in non-LTS releases, old
// releases, and "experimental releases" (newer than the toolchain version) being included in
// the default `check` suite.
System.getProperty("pklTestAllJdks")?.toBoolean() ?: PKL_TEST_ALL_JDKS
}
val testExperimentalJdks: Boolean by lazy {
System.getProperty("pklTestFutureJdks")?.toBoolean() ?: false
}
val testJdkVendors: Sequence<JvmVendorSpec> by lazy {
// By default, only OpenJDK is tested during multi-JDK testing. Flip `-DpklTestAllVendors=true`
// to additionally test against a suite of JDK vendors, including Azul, Oracle, and GraalVM.
when (System.getProperty("pklTestAllVendors")?.toBoolean()) {
true -> sequenceOf(JvmVendorSpec.ADOPTIUM, JvmVendorSpec.GRAAL_VM, JvmVendorSpec.ORACLE)
else -> sequenceOf(JvmVendorSpec.ADOPTIUM)
}
}
private val isArmWindows: Boolean
get() {
if (!os.isWindows) {
return false
}
// System.getProperty("os.arch") returns the architecture of the JVM, not the host OS.
val procArch = System.getenv("PROCESSOR_ARCHITECTURE")
return "ARM64".equals(procArch, ignoreCase = true)
}
// 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 {
if (isArmWindows) {
// Java toolchains does not work on ARM windows: https://github.com/gradle/gradle/issues/29807
// prevent creating tasks to test different JDKs if developing on a Windows ARM machine.
return@lazy listOf()
}
JavaVersionRange.inclusive(jdkTestFloor, jdkTestCeiling).toList()
}
val JavaLanguageVersion.isEnabled: Boolean
get() = isVersionEnabled(this)
fun isVersionEnabled(version: JavaLanguageVersion): Boolean {
return when {
testAllJdks -> true
multiJdkTesting -> JavaVersionRange.isLTS(version)
testExperimentalJdks -> version > jdkToolchainVersion
else -> false
}
}
private fun JavaToolchainSpec.pklJdkToolchain() {
languageVersion.set(jdkToolchainVersion)
vendor.set(jdkVendor)
}
private fun labelForVendor(vendor: JvmVendorSpec): String =
when (vendor) {
JvmVendorSpec.AZUL -> "Zulu"
JvmVendorSpec.GRAAL_VM -> "GraalVm"
JvmVendorSpec.ORACLE -> "Oracle"
JvmVendorSpec.ADOPTIUM -> "Adoptium"
else -> error("Unrecognized JDK vendor: $vendor")
}
private fun testNamer(baseName: () -> String): (JavaLanguageVersion, JvmVendorSpec?) -> String =
{ jdkTarget, vendor ->
val targetToken =
when (vendor) {
null -> "Jdk${jdkTarget.asInt()}"
else -> "Jdk${jdkTarget.asInt()}${labelForVendor(vendor).capitalized()}"
}
if (jdkTarget > jdkToolchainVersion) {
// test targets above the toolchain target are considered "experimental".
"${baseName()}${targetToken}Experimental"
} else {
"${baseName()}${targetToken}"
}
}
@Suppress("UnstableApiUsage")
fun multiJdkTestingWith(
templateTask: TaskProvider<out Test>,
configurator: MultiJdkTestConfigurator = {},
): Iterable<Provider<out Any>> =
with(project) {
val isMultiVendor = testJdkVendors.count() > 1
val baseNameProvider = { templateTask.get().name }
val namer = testNamer(baseNameProvider)
val applyConfig: MultiJdkTestConfigurator = { (version, jdk) ->
// 1) copy configurations from the template task
dependsOn(templateTask)
templateTask.get().let { template ->
classpath = template.classpath
testClassesDirs = template.testClassesDirs
jvmArgs.addAll(template.jvmArgs)
jvmArgumentProviders.addAll(template.jvmArgumentProviders)
forkEvery = template.forkEvery
maxParallelForks = template.maxParallelForks
minHeapSize = template.minHeapSize
maxHeapSize = template.maxHeapSize
exclude(template.excludes)
template.systemProperties.forEach { prop -> systemProperty(prop.key, prop.value) }
}
// 2) assign launcher
javaLauncher = jdk
// 3) dispatch the user's configurator
configurator(version to jdk)
}
serviceOf<JavaToolchainService>().let { toolchains ->
jdkTestRange
.flatMap { targetVersion ->
// multiply out by jdk vendor
testJdkVendors.map { vendor -> (targetVersion to vendor) }
}
.map { (jdkTarget, vendor) ->
if (jdkToolchainVersion == jdkTarget)
tasks.register(namer(jdkTarget, vendor)) {
// alias to `test`
dependsOn(templateTask)
group = Category.VERIFICATION
description =
"Alias for regular '${baseNameProvider()}' task, on JDK ${jdkTarget.asInt()}"
}
else
tasks.register(namer(jdkTarget, vendor.takeIf { isMultiVendor }), Test::class) {
enabled = jdkTarget.isEnabled
group = Category.VERIFICATION
description = "Run tests against JDK ${jdkTarget.asInt()}"
applyConfig(jdkTarget to toolchains.launcherFor { languageVersion = jdkTarget })
// fix: on jdk17, we must force the polyglot module on to the modulepath
if (jdkTarget.asInt() == 17)
jvmArgumentProviders.add(
CommandLineArgumentProvider {
buildList { listOf("--add-modules=org.graalvm.polyglot") }
}
)
}
}
.toList()
}
}
val javaCompiler: Provider<JavaCompiler> by lazy {
project.serviceOf<JavaToolchainService>().let { toolchainService ->
toolchainService.compilerFor { pklJdkToolchain() }
}
}
val javaTestLauncher: Provider<JavaLauncher> by lazy {
project.serviceOf<JavaToolchainService>().let { toolchainService ->
toolchainService.launcherFor { pklJdkToolchain() }
}
}
val multiJdkTesting: Boolean by lazy {
// Test Pkl against a full range of JDK versions, past and present, within the
// supported bounds of `PKL_TEST_JDK_TARGET` and `PKL_TEST_JDK_MAXIMUM`.
//
// In CI, this defaults to `true` to catch potential cross-JDK compat regressions or other bugs.
// In local dev, this defaults to `false` to speed up the build and reduce contributor load.
System.getProperty("pklMultiJdkTesting")?.toBoolean() ?: isCiBuild
}
val hasMuslToolchain: Boolean by lazy {
// see "install musl" in .circleci/jobs/BuildNativeJob.pkl
// see .github/scripts/install_musl.sh
File(System.getProperty("user.home"), "staticdeps/bin/x86_64-linux-musl-gcc").exists()
}
@@ -85,12 +365,15 @@ open class BuildInfo(project: Project) {
// could be `commitId: Provider<String> = project.provider { ... }`
val commitId: String by lazy {
// allow -DcommitId=abc123 for build environments that don't have git.
System.getProperty("commitId").let { if (it != null) return@lazy it }
// only run command once per build invocation
if (project === project.rootProject) {
val process = ProcessBuilder()
.command("git", "rev-parse", "--short", "HEAD")
.directory(project.rootDir)
.start()
val process =
ProcessBuilder()
.command("git", "rev-parse", "--short", "HEAD")
.directory(project.rootDir)
.start()
process.waitFor().also { exitCode ->
if (exitCode == -1) throw RuntimeException(process.errorStream.reader().readText())
}
@@ -100,9 +383,7 @@ open class BuildInfo(project: Project) {
}
}
val commitish: String by lazy {
if (isReleaseBuild) project.version.toString() else commitId
}
val commitish: String by lazy { if (isReleaseBuild) project.version.toString() else commitId }
val pklVersion: String by lazy {
if (isReleaseBuild) {
@@ -131,3 +412,7 @@ open class BuildInfo(project: Project) {
}
}
}
// Shape of a function which is applied to configure multi-JDK testing.
private typealias MultiJdkTestConfigurator =
Test.(Pair<JavaLanguageVersion, Provider<JavaLauncher>>) -> Unit

View File

@@ -1,39 +1,66 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
/**
* Builds a self-contained Pkl CLI Jar that is directly executable on *nix
* and executable with `java -jar` on Windows.
* Builds a self-contained Pkl CLI Jar that is directly executable on Windows, macOS, and Linux.
*
* For direct execution, the `java` command must be on the PATH.
*
* https://skife.org/java/unix/2011/06/20/really_executable_jars.html
* Technique borrowed from [Mill](https://mill-build.org/blog/5-executable-jars.html).
*/
abstract class ExecutableJar : DefaultTask() {
@get:InputFile
abstract val inJar: RegularFileProperty
@get:InputFile abstract val inJar: RegularFileProperty
@get:OutputFile
abstract val outJar: RegularFileProperty
@get:OutputFile abstract val outJar: RegularFileProperty
@get:Input
abstract val jvmArgs: ListProperty<String>
@get:Input abstract val jvmArgs: ListProperty<String>
@TaskAction
fun buildJar() {
val inFile = inJar.get().asFile
val outFile = outJar.get().asFile
val escapedJvmArgs = jvmArgs.get().joinToString(separator = " ") { "\"$it\"" }
val startScript = """
#!/bin/sh
exec java $escapedJvmArgs -jar $0 "$@"
""".trimIndent() + "\n\n\n"
val unixStartScript =
"""
@ 2>/dev/null # 2>nul & echo off & goto BOF
:
exec java $escapedJvmArgs -jar "$0" "$@"
exit
"""
.trimIndent()
val windowsStartScript =
"""
:BOF
setlocal
@echo off
java $escapedJvmArgs -jar "%~dpnx0" %*
endlocal
exit /B %errorlevel%
"""
.trimIndent()
// need crlf endings for Windows portion of script
.replace("\n", "\r\n")
val startScript = unixStartScript + "\r\n" + windowsStartScript + "\r\n".repeat(3)
outFile.outputStream().use { outStream ->
startScript.byteInputStream().use { it.copyTo(outStream) }
inFile.inputStream().use { it.copyTo(outStream) }

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

@@ -1,7 +1,22 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.gradle.util.GradleVersion
open class GradlePluginTests {
lateinit var minGradleVersion: GradleVersion
lateinit var maxGradleVersion: GradleVersion
var skippedGradleVersions: List<GradleVersion> = listOf()
}
}

View File

@@ -1,6 +1,21 @@
import org.gradle.util.GradleVersion
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import groovy.json.JsonSlurper
import java.net.URI
import org.gradle.util.GradleVersion
@Suppress("unused")
class GradleVersionInfo(json: Map<String, Any>) {
@@ -38,15 +53,19 @@ class GradleVersionInfo(json: Map<String, Any>) {
val wrapperChecksumUrl: String by json
companion object {
private fun fetchAll(): List<GradleVersionInfo> = fetchMultiple("https://services.gradle.org/versions/all")
private fun fetchAll(): List<GradleVersionInfo> =
fetchMultiple("https://services.gradle.org/versions/all")
fun fetchReleases(): List<GradleVersionInfo> = fetchAll().filter { it.isReleaseVersion }
fun fetchCurrent(): GradleVersionInfo = fetchSingle("https://services.gradle.org/versions/current")
fun fetchCurrent(): GradleVersionInfo =
fetchSingle("https://services.gradle.org/versions/current")
fun fetchRc(): GradleVersionInfo? = fetchSingleOrNull("https://services.gradle.org/versions/release-candidate")
fun fetchRc(): GradleVersionInfo? =
fetchSingleOrNull("https://services.gradle.org/versions/release-candidate")
fun fetchNightly(): GradleVersionInfo = fetchSingle("https://services.gradle.org/versions/nightly")
fun fetchNightly(): GradleVersionInfo =
fetchSingle("https://services.gradle.org/versions/nightly")
private fun fetchSingle(url: String): GradleVersionInfo {
@Suppress("UNCHECKED_CAST")
@@ -61,8 +80,9 @@ class GradleVersionInfo(json: Map<String, Any>) {
private fun fetchMultiple(url: String): List<GradleVersionInfo> {
@Suppress("UNCHECKED_CAST")
return (JsonSlurper().parse(URI(url).toURL()) as List<Map<String, Any>>)
.map { GradleVersionInfo(it) }
return (JsonSlurper().parse(URI(url).toURL()) as List<Map<String, Any>>).map {
GradleVersionInfo(it)
}
}
}
}

View File

@@ -1,6 +1,21 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.gradle.api.Project
import org.gradle.api.file.FileCollection
open class HtmlValidator(project: Project) {
var sources: FileCollection = project.files()
}
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.StandardCopyOption
import java.util.*
import javax.inject.Inject
import kotlin.io.path.createDirectories
import org.gradle.api.DefaultTask
import org.gradle.api.internal.file.FileOperations
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import org.gradle.process.ExecOperations
abstract class InstallGraalVm
@Inject
constructor(
private val fileOperations: FileOperations,
private val execOperations: ExecOperations,
) : DefaultTask() {
@get:Input abstract val graalVm: Property<BuildInfo.GraalVm>
init {
@Suppress("LeakingThis") onlyIf("GraalVM not installed") { !graalVm.get().installDir.exists() }
}
@TaskAction
@Suppress("unused")
fun run() {
// minimize chance of corruption by extract-to-random-dir-and-flip-symlink
val distroDir = Paths.get(graalVm.get().homeDir, UUID.randomUUID().toString())
try {
distroDir.createDirectories()
println("Extracting ${graalVm.get().downloadFile} into $distroDir")
// faster and more reliable than Gradle's `copy { from tarTree() }`
execOperations.exec {
workingDir = distroDir.toFile()
executable = "tar"
args("--strip-components=1", "-xzf", graalVm.get().downloadFile)
}
val os = org.gradle.internal.os.OperatingSystem.current()
val distroBinDir =
if (os.isMacOsX) distroDir.resolve("Contents/Home/bin") else distroDir.resolve("bin")
println("Installing native-image into $distroDir")
val gvmVersionMajor =
requireNotNull(graalVm.get().version.split(".").first().toIntOrNull()) {
"Invalid GraalVM JDK version: ${graalVm.get().graalVmJdkVersion}"
}
if (gvmVersionMajor < 24) {
execOperations.exec {
val executableName = if (os.isWindows) "gu.cmd" else "gu"
executable = distroBinDir.resolve(executableName).toString()
args("install", "--no-progress", "native-image")
}
}
println("Creating symlink ${graalVm.get().installDir} for $distroDir")
val tempLink = Paths.get(graalVm.get().homeDir, UUID.randomUUID().toString())
Files.createSymbolicLink(tempLink, distroDir)
try {
Files.move(tempLink, graalVm.get().installDir.toPath(), StandardCopyOption.ATOMIC_MOVE)
} catch (e: Exception) {
try {
fileOperations.delete(tempLink.toFile())
} catch (ignored: Exception) {}
throw e
}
} catch (e: Exception) {
try {
fileOperations.delete(distroDir)
} catch (ignored: Exception) {}
throw e
}
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:Suppress("MemberVisibilityCanBePrivate")
import java.util.*
import org.gradle.jvm.toolchain.JavaLanguageVersion
typealias JavaVersionPair = Pair<JavaLanguageVersion, JavaLanguageVersion>
// All LTS releases.
private val ltsReleases =
sortedSetOf(
JavaLanguageVersion.of(8),
JavaLanguageVersion.of(11),
JavaLanguageVersion.of(17),
JavaLanguageVersion.of(21),
)
/** Describes an inclusive range of JVM versions, based on the [JavaLanguageVersion] type. */
@JvmInline
value class JavaVersionRange private constructor(private val bounds: JavaVersionPair) :
Iterable<JavaLanguageVersion> {
@Suppress("unused")
companion object {
fun isLTS(version: JavaLanguageVersion): Boolean = version in ltsReleases
fun inclusive(floor: JavaLanguageVersion, ceiling: JavaLanguageVersion): JavaVersionRange =
JavaVersionRange(floor to ceiling)
fun startingAt(floor: JavaLanguageVersion): JavaVersionRange =
inclusive(floor, JavaLanguageVersion.of(PKL_TEST_JDK_MAXIMUM))
fun upTo(ceiling: JavaLanguageVersion): JavaVersionRange =
inclusive(JavaLanguageVersion.of(PKL_TEST_JDK_MINIMUM), ceiling)
}
operator fun contains(version: JavaLanguageVersion): Boolean =
version >= bounds.first && version <= bounds.second
fun asSequence(): Sequence<JavaLanguageVersion> = sequence {
var current = bounds.first
while (current <= bounds.second) {
yield(current)
current = JavaLanguageVersion.of(current.asInt() + 1)
}
}
fun asSortedSet(): SortedSet<JavaLanguageVersion> = asSequence().toSortedSet()
override fun iterator(): Iterator<JavaLanguageVersion> = asSortedSet().iterator()
}

View File

@@ -1,3 +1,18 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.File
import java.util.regex.Matcher
import java.util.regex.Pattern
@@ -15,21 +30,18 @@ import org.gradle.kotlin.dsl.listProperty
import org.gradle.kotlin.dsl.mapProperty
open class MergeSourcesJars : DefaultTask() {
@get:InputFiles
val inputJars: ConfigurableFileCollection = project.objects.fileCollection()
@get:InputFiles val inputJars: ConfigurableFileCollection = project.objects.fileCollection()
@get:InputFiles
val mergedBinaryJars: ConfigurableFileCollection = project.objects.fileCollection()
@get:Input
val relocatedPackages: MapProperty<String, String> = project.objects.mapProperty()
@get:Input val relocatedPackages: MapProperty<String, String> = project.objects.mapProperty()
@get:Input
var sourceFileExtensions: ListProperty<String> = project.objects.listProperty<String>()
.convention(listOf(".java", ".kt"))
var sourceFileExtensions: ListProperty<String> =
project.objects.listProperty<String>().convention(listOf(".java", ".kt"))
@get:OutputFile
val outputJar: RegularFileProperty = project.objects.fileProperty()
@get:OutputFile val outputJar: RegularFileProperty = project.objects.fileProperty()
@TaskAction
@Suppress("unused")
@@ -38,12 +50,15 @@ open class MergeSourcesJars : DefaultTask() {
val relocatedPkgs = relocatedPackages.get()
val relocatedPaths = relocatedPkgs.entries.associate { (key, value) -> toPath(key) to toPath(value) }
val relocatedPaths =
relocatedPkgs.entries.associate { (key, value) -> toPath(key) to toPath(value) }
// use negative lookbehind to match any that don't precede with
// a word or a period character. should catch most cases.
val importPattern = Pattern.compile("(?<!(\\w|\\.))(" +
relocatedPkgs.keys.joinToString("|") { it.replace(".", "\\.") } + ")")
val importPattern =
Pattern.compile(
"(?<!(\\w|\\.))(" + relocatedPkgs.keys.joinToString("|") { it.replace(".", "\\.") } + ")"
)
val sourceFileExts = sourceFileExtensions.get()
@@ -55,7 +70,7 @@ open class MergeSourcesJars : DefaultTask() {
val details = this
if (details.isDirectory) return@visit
var path = details.relativePath.parent.pathString
var path = details.relativePath.parent!!.pathString
val relocatedPath = relocatedPaths.keys.find { path.startsWith(it) }
if (relocatedPath != null) {
path = path.replace(relocatedPath, relocatedPaths.getValue(relocatedPath))
@@ -86,7 +101,7 @@ open class MergeSourcesJars : DefaultTask() {
project.zipTree(jar).visit {
val details = this
if (details.isDirectory) return@visit // avoid adding empty dirs
result.add(details.relativePath.parent.pathString)
result.add(details.relativePath.parent!!.pathString)
}
}
return result
@@ -96,7 +111,7 @@ open class MergeSourcesJars : DefaultTask() {
relocatedPkgs: Map<String, String>,
details: FileVisitDetails,
sourceText: String,
importPattern: Pattern
importPattern: Pattern,
): String {
val matcher = importPattern.matcher(sourceText)
val buffer = StringBuffer()

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

@@ -0,0 +1,66 @@
/*
* 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 com.diffplug.spotless.FormatterFunc
import com.diffplug.spotless.FormatterStep
import java.io.Serial
import java.io.Serializable
import java.net.URLClassLoader
import org.gradle.api.artifacts.Configuration
class PklFormatterStep(@Transient private val configuration: Configuration) : Serializable {
companion object {
@Serial private const val serialVersionUID: Long = 1L
}
fun create(): FormatterStep {
return FormatterStep.createLazy(
"pkl",
{ PklFormatterStep(configuration) },
{ PklFormatterFunc(configuration) },
)
}
}
class PklFormatterFunc(@Transient private val configuration: Configuration) :
FormatterFunc, Serializable {
companion object {
@Serial private const val serialVersionUID: Long = 1L
}
private val classLoader by lazy {
val urls = configuration.files.map { it.toURI().toURL() }
URLClassLoader(urls.toTypedArray())
}
private val formatterClass by lazy { classLoader.loadClass("org.pkl.formatter.Formatter") }
private val grammarVersionClass by lazy {
classLoader.loadClass("org.pkl.formatter.GrammarVersion")
}
private val grammarVersionLatestMethod by lazy { grammarVersionClass.getMethod("latest") }
private val formatMethod by lazy {
formatterClass.getMethod("format", String::class.java, grammarVersionClass)
}
private val formatterInstance by lazy { formatterClass.getConstructor().newInstance() }
override fun apply(input: String): String {
val latestGrammarVersion = grammarVersionLatestMethod(null)
return formatMethod(formatterInstance, input, latestGrammarVersion) as String
}
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.nio.charset.StandardCharsets
import java.util.Base64
import org.gradle.api.Project
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven
import org.gradle.api.publish.maven.tasks.GenerateMavenPom
import org.gradle.kotlin.dsl.*
import org.gradle.plugins.signing.SigningExtension
/** Configures common POM metadata (licenses, developers, SCM, etc.) for all Pkl publications. */
fun Project.configurePklPomMetadata() {
extensions.configure<PublishingExtension> {
publications.withType<MavenPublication>().configureEach {
pom {
name.set(artifactId)
licenses {
license {
name.set("The Apache Software License, Version 2.0")
url.set("https://github.com/apple/pkl/blob/main/LICENSE.txt")
}
}
developers {
developer {
id.set("pkl-authors")
name.set("The Pkl Authors")
email.set("pkl-oss@group.apple.com")
}
}
scm {
connection.set("scm:git:git://github.com/apple/pkl.git")
developerConnection.set("scm:git:ssh://github.com/apple/pkl.git")
val buildInfo = extensions.getByType<BuildInfo>()
url.set("https://github.com/apple/pkl/tree/${buildInfo.commitish}")
}
issueManagement {
system.set("GitHub Issues")
url.set("https://github.com/apple/pkl/issues")
}
ciManagement {
system.set("GitHub Actions")
url.set("https://github.com/apple/pkl/actions")
}
}
}
}
}
/** Configures POM validation task to check for unresolved versions and snapshots in releases. */
fun Project.configurePomValidation() {
val validatePom by
tasks.registering {
if (tasks.findByName("generatePomFileForLibraryPublication") == null) {
return@registering
}
val generatePomFileForLibraryPublication by tasks.existing(GenerateMavenPom::class)
val outputFile =
layout.buildDirectory.file("validatePom") // dummy output to satisfy up-to-date check
dependsOn(generatePomFileForLibraryPublication)
inputs.file(generatePomFileForLibraryPublication.get().destination)
outputs.file(outputFile)
doLast {
outputFile.get().asFile.delete()
val pomFile = generatePomFileForLibraryPublication.get().destination
assert(pomFile.exists())
val text = pomFile.readText()
run {
val unresolvedVersion = Regex("<version>.*[+,()\\[\\]].*</version>")
val matches = unresolvedVersion.findAll(text).toList()
if (matches.isNotEmpty()) {
throw org.gradle.api.GradleException(
"""
Found unresolved version selector(s) in generated POM:
${matches.joinToString("\n") { it.groupValues[0] }}
"""
.trimIndent()
)
}
}
val buildInfo = project.extensions.getByType<BuildInfo>()
if (buildInfo.isReleaseBuild) {
val snapshotVersion = Regex("<version>.*-SNAPSHOT</version>")
val matches = snapshotVersion.findAll(text).toList()
if (matches.isNotEmpty()) {
throw org.gradle.api.GradleException(
"""
Found snapshot version(s) in generated POM of Pkl release version:
${matches.joinToString("\n") { it.groupValues[0] }}
"""
.trimIndent()
)
}
}
outputFile.get().asFile.writeText("OK")
}
}
tasks.named("publish") { dependsOn(validatePom) }
}
/** Configures signing for Pkl publications. */
fun Project.configurePklSigning() {
// Workaround for maven publish plugin not setting up dependencies correctly.
// Taken from https://github.com/gradle/gradle/issues/26091#issuecomment-1798137734
val dependsOnTasks = mutableListOf<String>()
tasks.withType<AbstractPublishToMaven>().configureEach {
dependsOnTasks.add(name.replace("publish", "sign").replaceAfter("Publication", ""))
dependsOn(dependsOnTasks)
}
extensions.configure<SigningExtension> {
// provided as env vars `ORG_GRADLE_PROJECT_signingKey` and
// `ORG_GRADLE_PROJECT_signingPassword` in CI.
val signingKey =
(findProperty("signingKey") as String?)?.let {
Base64.getDecoder().decode(it).toString(StandardCharsets.US_ASCII)
}
val signingPassword = findProperty("signingPassword") as String?
if (signingKey != null && signingPassword != null) {
useInMemoryPgpKeys(signingKey, signingPassword)
}
extensions.getByType<PublishingExtension>().publications.findByName("library")?.let { sign(it) }
}
}

View File

@@ -1,3 +1,18 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.gradle.api.DefaultTask
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.result.ResolvedArtifactResult
@@ -12,27 +27,29 @@ import org.gradle.kotlin.dsl.property
import org.gradle.language.base.artifact.SourcesArtifact
open class ResolveSourcesJars : DefaultTask() {
@get:InputFiles
val configuration: Property<Configuration> = project.objects.property()
@get:InputFiles val configuration: Property<Configuration> = project.objects.property()
@get:OutputDirectory
val outputDir: DirectoryProperty = project.objects.directoryProperty()
@get:OutputDirectory val outputDir: DirectoryProperty = project.objects.directoryProperty()
@TaskAction
@Suppress("UnstableApiUsage", "unused")
fun resolve() {
val componentIds = configuration.get().incoming.resolutionResult.allDependencies.map {
(it as ResolvedDependencyResult).selected.id
}
val componentIds =
configuration.get().incoming.resolutionResult.allDependencies.map {
(it as ResolvedDependencyResult).selected.id
}
val resolutionResult = project.dependencies.createArtifactResolutionQuery()
.forComponents(componentIds)
.withArtifacts(JvmLibrary::class.java, SourcesArtifact::class.java)
.execute()
val resolutionResult =
project.dependencies
.createArtifactResolutionQuery()
.forComponents(componentIds)
.withArtifacts(JvmLibrary::class.java, SourcesArtifact::class.java)
.execute()
val resolvedJars = resolutionResult.resolvedComponents
.flatMap { it.getArtifacts(SourcesArtifact::class.java) }
.map { (it as ResolvedArtifactResult).file }
val resolvedJars =
resolutionResult.resolvedComponents
.flatMap { it.getArtifacts(SourcesArtifact::class.java) }
.map { (it as ResolvedArtifactResult).file }
// copying to an output dir because I don't know how else to describe task outputs
project.sync {

View File

@@ -1,10 +1,28 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
/*
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.diffplug.gradle.spotless.KotlinGradleExtension
import org.gradle.accessors.dm.LibrariesForLibs
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
plugins { id("com.diffplug.spotless") }
val buildInfo = extensions.create<BuildInfo>("buildInfo", project)
dependencyLocking {
lockAllConfigurations()
}
dependencyLocking { lockAllConfigurations() }
configurations {
val rejectedVersionSuffix = Regex("-alpha|-beta|-eap|-m|-rc|-snapshot", RegexOption.IGNORE_CASE)
@@ -13,8 +31,10 @@ configurations {
componentSelection {
all {
if (rejectedVersionSuffix.containsMatchIn(candidate.version)) {
reject("Rejected dependency $candidate " +
"because it has a prelease version suffix matching `$rejectedVersionSuffix`.")
reject(
"Rejected dependency $candidate " +
"because it has a prelease version suffix matching `$rejectedVersionSuffix`."
)
}
}
}
@@ -22,38 +42,35 @@ configurations {
}
}
plugins.withType(JavaPlugin::class).configureEach {
val java = project.extensions.getByType<JavaPluginExtension>()
java.sourceCompatibility = JavaVersion.VERSION_17
java.targetCompatibility = JavaVersion.VERSION_17
configurations.all {
resolutionStrategy.eachDependency {
if (requested.group == "org.jetbrains.kotlin") {
// prevent transitive deps from bumping Koltin version
useVersion(libs.versions.kotlin.get())
}
}
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = "17"
freeCompilerArgs = freeCompilerArgs + listOf("-Xjsr305=strict", "-Xjvm-default=all")
plugins.withType(JavaPlugin::class).configureEach {
tasks.withType<JavaCompile>().configureEach { options.release = 17 }
}
tasks.withType<KotlinJvmCompile>().configureEach {
compilerOptions {
jvmTarget = JvmTarget.JVM_17
freeCompilerArgs.addAll("-Xjsr305=strict", "-Xjvm-default=all")
freeCompilerArgs.add("-Xjdk-release=17")
}
}
plugins.withType(IdeaPlugin::class).configureEach {
val errorMessage = "Use IntelliJ Gradle import instead of running the `idea` task. See README for more information."
val errorMessage =
"Use IntelliJ Gradle import instead of running the `idea` task. See README for more information."
tasks.named("idea") {
doFirst {
throw GradleException(errorMessage)
}
}
tasks.named("ideaModule") {
doFirst {
throw GradleException(errorMessage)
}
}
tasks.named("idea") { doFirst { throw GradleException(errorMessage) } }
tasks.named("ideaModule") { doFirst { throw GradleException(errorMessage) } }
if (project == rootProject) {
tasks.named("ideaProject") {
doFirst {
throw GradleException(errorMessage)
}
}
tasks.named("ideaProject") { doFirst { throw GradleException(errorMessage) } }
}
}
@@ -64,7 +81,7 @@ plugins.withType(MavenPublishPlugin::class).configureEach {
repositories {
maven {
name = "projectLocal" // affects task names
url = uri("file:///$rootDir/build/m2")
url = rootDir.resolve("build/m2").toURI()
}
}
// use resolved/locked (e.g., `1.15`)
@@ -72,11 +89,7 @@ plugins.withType(MavenPublishPlugin::class).configureEach {
// dependency versions in generated POMs
publications {
withType(MavenPublication::class.java) {
versionMapping {
allVariants {
fromResolutionResult()
}
}
versionMapping { allVariants { fromResolutionResult() } }
}
}
}
@@ -84,13 +97,10 @@ plugins.withType(MavenPublishPlugin::class).configureEach {
// settings.gradle.kts sets `--write-locks`
// if Gradle command line contains this task name
val updateDependencyLocks by tasks.registering {
doLast {
configurations
.filter { it.isCanBeResolved }
.forEach { it.resolve() }
val updateDependencyLocks by
tasks.registering {
doLast { configurations.filter { it.isCanBeResolved }.forEach { it.resolve() } }
}
}
val allDependencies by tasks.registering(DependencyReportTask::class)
@@ -118,3 +128,49 @@ tasks.withType(JavaExec::class).configureEach {
server = true
}
}
// Version Catalog library symbols.
private val libs = the<LibrariesForLibs>()
private val licenseHeaderFile by lazy {
rootProject.file("buildSrc/src/main/resources/license-header.star-block.txt")
}
private fun KotlinGradleExtension.configureFormatter() {
ktfmt(libs.versions.ktfmt.get()).googleStyle()
licenseHeaderFile(licenseHeaderFile, "([a-zA-Z]|@file|//)")
}
val originalRemoteName = System.getenv("PKL_ORIGINAL_REMOTE_NAME") ?: "origin"
// if we're running against a release branch (or a PR targeted at one), use that branch for
// ratcheting
// these env vars are set by GitHub actions:
// https://docs.github.com/en/actions/reference/workflows-and-actions/variables#default-environment-variables
val ratchetBranchName =
(System.getenv("GITHUB_BASE_REF") ?: System.getenv("GITHUB_REF_NAME"))?.let {
if (it.startsWith("release/")) it else null
} ?: "main"
spotless {
ratchetFrom = "$originalRemoteName/$ratchetBranchName"
// When building root project, format buildSrc files too.
// We need this because buildSrc is not a subproject of the root project, so a top-level
// `spotlessApply` will not trigger `buildSrc:spotlessApply`.
if (project === rootProject) {
kotlinGradle {
configureFormatter()
target("*.kts", "buildSrc/*.kts", "buildSrc/src/*/kotlin/**/*.kts")
}
kotlin {
ktfmt(libs.versions.ktfmt.get()).googleStyle()
target("buildSrc/src/*/kotlin/**/*.kt")
licenseHeaderFile(licenseHeaderFile)
}
} else {
kotlinGradle {
configureFormatter()
target("*.kts")
}
}
}

View File

@@ -1,6 +1,20 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.gradle.api.GradleException
import org.gradle.api.artifacts.Configuration
import org.gradle.api.component.AdhocComponentWithVariants
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.testing.Test
@@ -9,7 +23,7 @@ import org.gradle.kotlin.dsl.*
plugins {
`java-library`
`maven-publish`
id("com.github.johnrengelman.shadow")
id("com.gradleup.shadow")
}
// make fat Jar available to other subprojects
@@ -18,43 +32,59 @@ val fatJarConfiguration: Configuration = configurations.create("fatJar")
val fatJarPublication: MavenPublication = publishing.publications.create<MavenPublication>("fatJar")
// ideally we'd configure this automatically based on project dependencies
val firstPartySourcesJarsConfiguration: Configuration = configurations.create("firstPartySourcesJars")
val firstPartySourcesJarsConfiguration: Configuration =
configurations.create("firstPartySourcesJars")
val relocations = mapOf(
// pkl-core dependencies
"org.antlr.v4." to "org.pkl.thirdparty.antlr.v4.",
"com.oracle.truffle" to "org.pkl.thirdparty.truffle",
"org.graalvm." to "org.pkl.thirdparty.graalvm.",
"org.organicdesign.fp." to "org.pkl.thirdparty.paguro.",
"org.snakeyaml.engine." to "org.pkl.thirdparty.snakeyaml.engine.",
"org.msgpack." to "org.pkl.thirdparty.msgpack.",
"org.w3c.dom." to "org.pkl.thirdparty.w3c.dom",
"com.oracle.svm.core." to "org.pkl.thirdparty.svm.",
val relocations =
mapOf(
// pkl-core dependencies
"org.organicdesign.fp." to "org.pkl.thirdparty.paguro.",
"org.snakeyaml.engine." to "org.pkl.thirdparty.snakeyaml.engine.",
"org.msgpack." to "org.pkl.thirdparty.msgpack.",
"org.w3c.dom." to "org.pkl.thirdparty.w3c.dom.",
"com.oracle.svm.core." to "org.pkl.thirdparty.svm.",
// pkl-cli dependencies
"org.jline." to "org.pkl.thirdparty.jline.",
"com.github.ajalt.clikt." to "org.pkl.thirdparty.clikt.",
"kotlin." to "org.pkl.thirdparty.kotlin.",
"kotlinx." to "org.pkl.thirdparty.kotlinx.",
"org.intellij." to "org.pkl.thirdparty.intellij.",
"org.fusesource.jansi." to "org.pkl.thirdparty.jansi",
"org.fusesource.hawtjni." to "org.pkl.thirdparty.hawtjni",
// pkl-cli dependencies
"org.jline." to "org.pkl.thirdparty.jline.",
"com.github.ajalt.clikt." to "org.pkl.thirdparty.clikt.",
"com.github.ajalt.colormath." to "org.pkl.thirdparty.colormath.",
"com.github.ajalt.mordant." to "org.pkl.thirdparty.mordant.",
"com.sun.jna." to "org.pkl.thirdparty.jna.",
"kotlin." to "org.pkl.thirdparty.kotlin.",
"kotlinx." to "org.pkl.thirdparty.kotlinx.",
"org.intellij." to "org.pkl.thirdparty.intellij.",
"org.fusesource.jansi." to "org.pkl.thirdparty.jansi.",
"org.fusesource.hawtjni." to "org.pkl.thirdparty.hawtjni.",
// pkl-doc dependencies
"org.commonmark." to "org.pkl.thirdparty.commonmark.",
"org.jetbrains." to "org.pkl.thirdparty.jetbrains.",
// pkl-config-java dependencies
"io.leangen.geantyref." to "org.pkl.thirdparty.geantyref.",
// pkl-doc dependencies
"org.commonmark." to "org.pkl.thirdparty.commonmark.",
"org.jetbrains." to "org.pkl.thirdparty.jetbrains.",
"_COROUTINE." to "org.pkl.thirdparty.kotlinx._COROUTINE.",
// pkl-codegen-java dependencies
"com.squareup.javapoet." to "org.pkl.thirdparty.javapoet.",
// pkl-config-java dependencies
"io.leangen.geantyref." to "org.pkl.thirdparty.geantyref.",
// pkl-codegen-kotlin dependencies
"com.squareup.kotlinpoet." to "org.pkl.thirdparty.kotlinpoet.",
)
// pkl-codegen-java dependencies
"com.palantir.javapoet." to "org.pkl.thirdparty.javapoet.",
val nonRelocations = listOf("com/oracle/truffle/")
// pkl-codegen-kotlin dependencies
"com.squareup.kotlinpoet." to "org.pkl.thirdparty.kotlinpoet.",
)
for ((key, value) in relocations) {
if (!key.endsWith(".")) {
throw GradleException(
"Invalid relocation `\"$key\" to \"$value\"`: `$key` should end with a dot"
)
}
if (!value.endsWith(".")) {
throw GradleException(
"Invalid relocation `\"$key\" to \"$value\"`: `$value` should end with a dot"
)
}
}
val nonRelocations = listOf("com/oracle/truffle/", "org/graalvm/")
tasks.shadowJar {
inputs.property("relocations", relocations)
@@ -63,12 +93,32 @@ tasks.shadowJar {
configurations = listOf(project.configurations.runtimeClasspath.get())
addMultiReleaseAttribute = true
// not required at runtime / fat JARs can't be used in native-image builds anyway
exclude("org/pkl/cli/svm/**")
exclude("META-INF/maven/**")
exclude("META-INF/upgrade/**")
exclude("META-INF/versions/19/**")
// org.antlr.v4.runtime.misc.RuleDependencyProcessor
exclude("META-INF/services/javax.annotation.processing.Processor")
exclude("DebugProbesKt.bin")
val info = project.extensions.getByType<BuildInfo>()
val minimumJvmTarget = JavaVersion.toVersion(info.jvmTarget)
manifest.attributes(
// Certain exports need to be added to the Java modulepath for Java 17 to work properly with
// shaded JARs. See the following link for an explanation of this syntax:
// https://bugs.openjdk.org/browse/JDK-8335225
"Add-Exports" to info.jpmsExportsForJarManifest
)
// effectively, this results in calls excluding:
// `META-INF/versions/{18-25}/**`
// at the time of this writing; multi-release JARs beyond JDK 21 break the current
// version of the Shadow plugin, and aren't needed for Truffle's use by Pkl.
JavaVersionRange.startingAt(JavaLanguageVersion.of(minimumJvmTarget.majorVersion.toInt() + 1))
.forEach { exclude("META-INF/versions/${it.asInt()}/**") }
exclude("module-info.*")
@@ -80,101 +130,93 @@ tasks.shadowJar {
mergeServiceFiles()
}
// workaround for https://github.com/johnrengelman/shadow/issues/651
components.withType(AdhocComponentWithVariants::class.java).forEach { c ->
c.withVariantsFromConfiguration(project.configurations.shadowRuntimeElements.get()) {
skip()
shadow { addShadowVariantIntoJavaComponent = false }
val testFatJar by
tasks.registering(Test::class) {
testClassesDirs = files(tasks.test.get().testClassesDirs)
classpath =
// compiled test classes
sourceSets.test.get().output +
// fat Jar
tasks.shadowJar.get().outputs.files +
// test-only dependencies
// (test dependencies that are also main dependencies must already be contained in fat Jar;
// to verify that, we don't want to include them here)
(configurations.testRuntimeClasspath.get() - configurations.runtimeClasspath.get())
}
}
val testFatJar by tasks.registering(Test::class) {
testClassesDirs = files(tasks.test.get().testClassesDirs)
classpath =
// compiled test classes
sourceSets.test.get().output +
// fat Jar
tasks.shadowJar.get().outputs.files +
// test-only dependencies
// (test dependencies that are also main dependencies must already be contained in fat Jar;
// to verify that, we don't want to include them here)
(configurations.testRuntimeClasspath.get() - configurations.runtimeClasspath.get())
}
tasks.check { dependsOn(testFatJar) }
tasks.check {
dependsOn(testFatJar)
}
val validateFatJar by
tasks.registering {
val outputFile = layout.buildDirectory.file("validateFatJar/result.txt")
inputs.files(tasks.shadowJar)
inputs.property("nonRelocations", nonRelocations)
outputs.file(outputFile)
val validateFatJar by tasks.registering {
val outputFile = layout.buildDirectory.file("validateFatJar/result.txt")
inputs.files(tasks.shadowJar)
inputs.property("nonRelocations", nonRelocations)
outputs.file(outputFile)
doLast {
val unshadowedFiles = mutableListOf<String>()
zipTree(tasks.shadowJar.get().outputs.files.singleFile).visit {
val fileDetails = this
val path = fileDetails.relativePath.pathString
if (!(fileDetails.isDirectory ||
path.startsWith("org/pkl/") ||
path.startsWith("META-INF/") ||
nonRelocations.any { path.startsWith(it) })) {
// don't throw exception inside `visit`
// as this gives a misleading "Could not expand ZIP" error message
unshadowedFiles.add(path)
doLast {
val unshadowedFiles = mutableListOf<String>()
zipTree(tasks.shadowJar.get().outputs.files.singleFile).visit {
val fileDetails = this
val path = fileDetails.relativePath.pathString
if (
!(fileDetails.isDirectory ||
path.startsWith("org/pkl/") ||
path.startsWith("META-INF/") ||
nonRelocations.any { path.startsWith(it) })
) {
// don't throw exception inside `visit`
// as this gives a misleading "Could not expand ZIP" error message
unshadowedFiles.add(path)
}
}
if (unshadowedFiles.isEmpty()) {
outputFile.get().asFile.writeText("SUCCESS")
} else {
outputFile.get().asFile.writeText("FAILURE")
throw GradleException("Found unshadowed files:\n" + unshadowedFiles.joinToString("\n"))
}
}
if (unshadowedFiles.isEmpty()) {
outputFile.get().asFile.writeText("SUCCESS")
} else {
outputFile.get().asFile.writeText("FAILURE")
throw GradleException("Found unshadowed files:\n" + unshadowedFiles.joinToString("\n"))
}
}
}
tasks.check {
dependsOn(validateFatJar)
}
val resolveSourcesJars by tasks.registering(ResolveSourcesJars::class) {
configuration.set(configurations.runtimeClasspath)
outputDir.set(layout.buildDirectory.dir("resolveSourcesJars"))
}
tasks.check { dependsOn(validateFatJar) }
val fatSourcesJar by tasks.registering(MergeSourcesJars::class) {
plugins.withId("pklJavaLibrary") {
inputJars.from(tasks.named("sourcesJar"))
val resolveSourcesJars by
tasks.registering(ResolveSourcesJars::class) {
configuration.set(configurations.runtimeClasspath)
outputDir.set(layout.buildDirectory.dir("resolveSourcesJars"))
}
inputJars.from(firstPartySourcesJarsConfiguration)
inputJars.from(resolveSourcesJars.map { fileTree(it.outputDir) })
mergedBinaryJars.from(tasks.shadowJar)
relocatedPackages.set(relocations)
outputJar.fileProvider(provider {
file(tasks.shadowJar.get().archiveFile.get().asFile.path.replace(".jar", "-sources.jar"))
})
}
val fatSourcesJar by
tasks.registering(MergeSourcesJars::class) {
plugins.withId("pklJavaLibrary") { inputJars.from(tasks.named("sourcesJar")) }
inputJars.from(firstPartySourcesJarsConfiguration)
inputJars.from(resolveSourcesJars.map { fileTree(it.outputDir) })
artifacts {
add("fatJar", tasks.shadowJar)
}
mergedBinaryJars.from(tasks.shadowJar)
relocatedPackages.set(relocations)
outputJar.fileProvider(
provider {
file(tasks.shadowJar.get().archiveFile.get().asFile.path.replace(".jar", "-sources.jar"))
}
)
}
artifacts { add("fatJar", tasks.shadowJar) }
publishing {
publications {
named<MavenPublication>("fatJar") {
project.shadow.component(this)
from(components["shadow"])
// sources Jar is fat
artifact(fatSourcesJar.flatMap { it.outputJar.asFile }) {
classifier = "sources"
}
artifact(fatSourcesJar.flatMap { it.outputJar.asFile }) { classifier = "sources" }
plugins.withId("pklJavaLibrary") {
val javadocJar by tasks.existing(Jar::class)
// Javadoc Jar is not fat (didn't invest effort)
artifact(javadocJar.flatMap { it.archiveFile }) {
classifier = "javadoc"
}
artifact(javadocJar.flatMap { it.archiveFile }) { classifier = "javadoc" }
}
}
}

View File

@@ -1,36 +1,35 @@
import java.nio.file.*
import java.util.UUID
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import de.undercouch.gradle.tasks.download.Download
import de.undercouch.gradle.tasks.download.Verify
import kotlin.io.path.createDirectories
plugins {
id("de.undercouch.download")
}
plugins { id("de.undercouch.download") }
val buildInfo = project.extensions.getByType<BuildInfo>()
val BuildInfo.GraalVm.downloadFile get(): File {
val extension = if (buildInfo.os.isWindows) "zip" else "tar.gz"
return file(homeDir).resolve("${baseName}.$extension")
}
// tries to minimize chance of corruption by download-to-temp-file-and-move
val downloadGraalVmAarch64 by tasks.registering(Download::class) {
configureDownloadGraalVm(buildInfo.graalVmAarch64)
}
val downloadGraalVmAarch64 by
tasks.registering(Download::class) { configureDownloadGraalVm(buildInfo.graalVmAarch64) }
val downloadGraalVmAmd64 by tasks.registering(Download::class) {
configureDownloadGraalVm(buildInfo.graalVmAmd64)
}
val downloadGraalVmAmd64 by
tasks.registering(Download::class) { configureDownloadGraalVm(buildInfo.graalVmAmd64) }
fun Download.configureDownloadGraalVm(graalvm: BuildInfo.GraalVm) {
onlyIf {
!graalvm.installDir.exists()
}
doLast {
println("Downloaded GraalVm to ${graalvm.downloadFile}")
}
onlyIf { !graalvm.installDir.exists() }
doLast { println("Downloaded GraalVm to ${graalvm.downloadFile}") }
src(graalvm.downloadUrl)
dest(graalvm.downloadFile)
@@ -38,77 +37,38 @@ fun Download.configureDownloadGraalVm(graalvm: BuildInfo.GraalVm) {
tempAndMove(true)
}
val verifyGraalVmAarch64 by tasks.registering(Verify::class) {
configureVerifyGraalVm(buildInfo.graalVmAarch64)
dependsOn(downloadGraalVmAarch64)
}
val verifyGraalVmAmd64 by tasks.registering(Verify::class) {
configureVerifyGraalVm(buildInfo.graalVmAmd64)
dependsOn(downloadGraalVmAmd64)
}
fun Verify.configureVerifyGraalVm(graalvm: BuildInfo.GraalVm) {
onlyIf {
!graalvm.installDir.exists()
val verifyGraalVmAarch64 by
tasks.registering(Verify::class) {
configureVerifyGraalVm(buildInfo.graalVmAarch64)
dependsOn(downloadGraalVmAarch64)
}
val verifyGraalVmAmd64 by
tasks.registering(Verify::class) {
configureVerifyGraalVm(buildInfo.graalVmAmd64)
dependsOn(downloadGraalVmAmd64)
}
fun Verify.configureVerifyGraalVm(graalvm: BuildInfo.GraalVm) {
onlyIf { !graalvm.installDir.exists() }
src(graalvm.downloadFile)
checksum(buildInfo.libs.findVersion("graalVmSha256-${graalvm.osName}-${graalvm.arch}").get().toString())
checksum(
buildInfo.libs.findVersion("graalVmSha256-${graalvm.osName}-${graalvm.arch}").get().toString()
)
algorithm("SHA-256")
}
// minimize chance of corruption by extract-to-random-dir-and-flip-symlink
val installGraalVmAarch64 by tasks.registering {
dependsOn(verifyGraalVmAarch64)
configureInstallGraalVm(buildInfo.graalVmAarch64)
}
// minimize chance of corruption by extract-to-random-dir-and-flip-symlink
val installGraalVmAmd64 by tasks.registering {
dependsOn(verifyGraalVmAmd64)
configureInstallGraalVm(buildInfo.graalVmAmd64)
}
fun Task.configureInstallGraalVm(graalVm: BuildInfo.GraalVm) {
onlyIf {
!graalVm.installDir.exists()
@Suppress("unused")
val installGraalVmAarch64 by
tasks.registering(InstallGraalVm::class) {
dependsOn(verifyGraalVmAarch64)
graalVm = buildInfo.graalVmAarch64
}
doLast {
val distroDir = Paths.get(graalVm.homeDir, UUID.randomUUID().toString())
try {
distroDir.createDirectories()
println("Extracting ${graalVm.downloadFile} into $distroDir")
// faster and more reliable than Gradle's `copy { from tarTree() }`
exec {
workingDir = file(distroDir)
executable = "tar"
args("--strip-components=1", "-xzf", graalVm.downloadFile)
}
val distroBinDir = if (buildInfo.os.isMacOsX) distroDir.resolve("Contents/Home/bin") else distroDir.resolve("bin")
println("Installing native-image into $distroDir")
exec {
val executableName = if (buildInfo.os.isWindows) "gu.cmd" else "gu"
executable = distroBinDir.resolve(executableName).toString()
args("install", "--no-progress", "native-image")
}
println("Creating symlink ${graalVm.installDir} for $distroDir")
val tempLink = Paths.get(graalVm.homeDir, UUID.randomUUID().toString())
Files.createSymbolicLink(tempLink, distroDir)
try {
Files.move(tempLink, graalVm.installDir.toPath(), StandardCopyOption.ATOMIC_MOVE)
} catch (e: Exception) {
try { delete(tempLink.toFile()) } catch (ignored: Exception) {}
throw e
}
} catch (e: Exception) {
try { delete(distroDir) } catch (ignored: Exception) {}
throw e
}
@Suppress("unused")
val installGraalVmAmd64 by
tasks.registering(InstallGraalVm::class) {
dependsOn(verifyGraalVmAmd64)
graalVm = buildInfo.graalVmAmd64
}
}

View File

@@ -1,19 +1,19 @@
/**
* Allows to run Gradle plugin tests against different Gradle versions.
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Adds a `compatibilityTestX` task for every Gradle version X
* between `ext.minSupportedGradleVersion` and `ext.maxSupportedGradleVersion`
* that is not in `ext.gradleVersionsExcludedFromTesting`.
* The list of available Gradle versions is obtained from services.gradle.org.
* Adds lifecycle tasks to test against multiple Gradle versions at once, for example all Gradle release versions.
* Compatibility test tasks run the same tests and use the same task configuration as the project's `test` task.
* They set system properties for the Gradle version and distribution URL to be used.
* These properties are consumed by the `AbstractTest` class.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
plugins {
java
}
plugins { java }
val gradlePluginTests = extensions.create<GradlePluginTests>("gradlePluginTests")
@@ -24,18 +24,26 @@ tasks.addRule("Pattern: compatibilityTest[All|Releases|Latest|Candidate|Nightly|
when (val taskNameSuffix = matchResult.groupValues[1]) {
"All" ->
task("compatibilityTestAll") {
dependsOn("compatibilityTestReleases", "compatibilityTestCandidate", "compatibilityTestNightly")
dependsOn(
"compatibilityTestReleases",
"compatibilityTestCandidate",
"compatibilityTestNightly",
)
}
// releases in configured range
"Releases" ->
task("compatibilityTestReleases") {
val versionInfos = GradleVersionInfo.fetchReleases()
val versionsToTestAgainst = versionInfos.filter { versionInfo ->
val v = versionInfo.gradleVersion
!versionInfo.broken &&
v in gradlePluginTests.minGradleVersion..gradlePluginTests.maxGradleVersion &&
v !in gradlePluginTests.skippedGradleVersions
}
val allVersions =
versionInfos
.filter { versionInfo ->
val v = versionInfo.gradleVersion
!versionInfo.broken &&
v in gradlePluginTests.minGradleVersion..gradlePluginTests.maxGradleVersion &&
v !in gradlePluginTests.skippedGradleVersions
}
.sortedBy { it.gradleVersion }
val versionsToTestAgainst = listOf(allVersions.first(), allVersions.last())
dependsOn(versionsToTestAgainst.map { createCompatibilityTestTask(it) })
}
@@ -45,8 +53,10 @@ tasks.addRule("Pattern: compatibilityTest[All|Releases|Latest|Candidate|Nightly|
val versionInfo = GradleVersionInfo.fetchCurrent()
if (versionInfo.version == gradle.gradleVersion) {
doLast {
println("No new Gradle release available. " +
"(Run `gradlew test` to test against ${versionInfo.version}.)")
println(
"No new Gradle release available. " +
"(Run `gradlew test` to test against ${versionInfo.version}.)"
)
}
} else {
dependsOn(createCompatibilityTestTask(versionInfo))
@@ -59,9 +69,7 @@ tasks.addRule("Pattern: compatibilityTest[All|Releases|Latest|Candidate|Nightly|
if (versionInfo?.activeRc == true) {
dependsOn(createCompatibilityTestTask(versionInfo))
} else {
doLast {
println("No active Gradle release candidate available.")
}
doLast { println("No active Gradle release candidate available.") }
}
}
// latest nightly
@@ -73,17 +81,17 @@ tasks.addRule("Pattern: compatibilityTest[All|Releases|Latest|Candidate|Nightly|
// explicit version
else ->
createCompatibilityTestTask(
taskNameSuffix,
"https://services.gradle.org/distributions-snapshots/gradle-$taskNameSuffix-bin.zip"
taskNameSuffix,
"https://services.gradle.org/distributions-snapshots/gradle-$taskNameSuffix-bin.zip",
)
}
}
fun createCompatibilityTestTask(versionInfo: GradleVersionInfo): Task =
createCompatibilityTestTask(versionInfo.version, versionInfo.downloadUrl)
fun createCompatibilityTestTask(versionInfo: GradleVersionInfo): TaskProvider<Test> =
createCompatibilityTestTask(versionInfo.version, versionInfo.downloadUrl)
fun createCompatibilityTestTask(version: String, downloadUrl: String): Task {
return tasks.create("compatibilityTest$version", Test::class.java) {
fun createCompatibilityTestTask(version: String, downloadUrl: String): TaskProvider<Test> {
return tasks.register("compatibilityTest$version", Test::class.java) {
mustRunAfter(tasks.test)
maxHeapSize = tasks.test.get().maxHeapSize

View File

@@ -1,20 +1,33 @@
plugins {
base
}
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
plugins { base }
val htmlValidator = extensions.create<HtmlValidator>("htmlValidator", project)
val buildInfo = project.extensions.getByType<BuildInfo>()
val validatorConfiguration: Configuration = configurations.create("validator") {
resolutionStrategy.eachDependency {
if (requested.group == "log4j" && requested.name == "log4j") {
@Suppress("UnstableApiUsage")
useTarget(buildInfo.libs.findLibrary("log4j12Api").get())
because("mitigate critical security vulnerabilities")
val validatorConfiguration: Configuration =
configurations.create("validator") {
resolutionStrategy.eachDependency {
if (requested.group == "log4j" && requested.name == "log4j") {
@Suppress("UnstableApiUsage") useTarget(buildInfo.libs.findLibrary("log4j12Api").get())
because("mitigate critical security vulnerabilities")
}
}
}
}
dependencies {
@Suppress("UnstableApiUsage")
@@ -32,27 +45,29 @@ dependencies {
}
}
val validateHtml by tasks.registering(JavaExec::class) {
val resultFile = layout.buildDirectory.file("validateHtml/result.txt")
inputs.files(htmlValidator.sources)
outputs.file(resultFile)
val validateHtml by
tasks.registering(JavaExec::class) {
val resultFile = layout.buildDirectory.file("validateHtml/result.txt")
inputs.files(htmlValidator.sources)
outputs.file(resultFile)
classpath = validatorConfiguration
mainClass.set("nu.validator.client.SimpleCommandLineValidator")
args("--skip-non-html") // --also-check-css doesn't work (still checks css as html), so limit to html files
args("--filterpattern", "(.*)Consider adding “lang=(.*)")
args("--filterpattern", "(.*)Consider adding a “lang” attribute(.*)")
args("--filterpattern", "(.*)unrecognized media “amzn-kf8”(.*)") // kindle
// for debugging
// args "--verbose"
args(htmlValidator.sources)
classpath = validatorConfiguration
mainClass.set("nu.validator.client.SimpleCommandLineValidator")
args(
"--skip-non-html"
) // --also-check-css doesn't work (still checks css as html), so limit to html files
args("--filterpattern", "(.*)Consider adding “lang=(.*)")
args("--filterpattern", "(.*)Consider adding a “lang” attribute(.*)")
args("--filterpattern", "(.*)unrecognized media “amzn-kf8”(.*)") // kindle
// for debugging
// args "--verbose"
args(htmlValidator.sources)
// write a basic result file s.t. gradle can consider task up-to-date
// writing a result file in case validation fails is not easily possible with JavaExec, but also not strictly necessary
doFirst { project.delete(resultFile) }
doLast { resultFile.get().asFile.writeText("Success.") }
}
// write a basic result file s.t. gradle can consider task up-to-date
// writing a result file in case validation fails is not easily possible with JavaExec, but also
// not strictly necessary
doFirst { project.delete(resultFile) }
doLast { resultFile.get().asFile.writeText("Success.") }
}
tasks.check {
dependsOn(validateHtml)
}
tasks.check { dependsOn(validateHtml) }

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

@@ -1,22 +1,47 @@
@file:Suppress("HttpUrlsUsage")
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:Suppress("HttpUrlsUsage", "unused")
import org.gradle.accessors.dm.LibrariesForLibs
plugins {
`java-library`
`jvm-toolchains`
`jvm-test-suite`
id("pklKotlinTest")
id("com.diffplug.spotless")
}
// make sources Jar available to other subprojects
val sourcesJarConfiguration = configurations.register("sourcesJar")
val sourcesJarConfiguration: Provider<Configuration> = configurations.register("sourcesJar")
// Version Catalog library symbols.
val libs = the<LibrariesForLibs>()
// Build configuration.
val info = project.extensions.getByType<BuildInfo>()
java {
withSourcesJar() // creates `sourcesJar` task
withJavadocJar()
toolchain {
languageVersion = info.jdkToolchainVersion
vendor = info.jdkVendor
}
}
artifacts {
@@ -27,18 +52,25 @@ artifacts {
spotless {
java {
googleJavaFormat(libs.versions.googleJavaFormat.get())
targetExclude("**/generated/**", "**/build/**")
target("src/*/java/**/*.java")
licenseHeaderFile(rootProject.file("buildSrc/src/main/resources/license-header.star-block.txt"))
}
kotlin {
ktfmt(libs.versions.ktfmt.get()).googleStyle()
target("src/*/kotlin/**/*.kt")
licenseHeaderFile(rootProject.file("buildSrc/src/main/resources/license-header.star-block.txt"))
}
}
tasks.compileKotlin {
enabled = false
}
tasks.compileKotlin { enabled = false }
tasks.jar {
manifest {
attributes += mapOf("Automatic-Module-Name" to "org.${project.name.replace("-", ".")}")
attributes +=
mapOf(
"Automatic-Module-Name" to "org.${project.name.replace("-", ".")}",
"Add-Exports" to info.jpmsExportsForJarManifest,
)
}
}
@@ -49,19 +81,59 @@ tasks.javadoc {
(options as StandardJavadocDocletOptions).addStringOption("Xdoclint:none", "-quiet")
}
val workAroundKotlinGradlePluginBug by tasks.registering {
doLast {
// Works around this problem, which sporadically appears and disappears in different subprojects:
// A problem was found with the configuration of task ':pkl-executor:compileJava' (type 'JavaCompile').
// > Directory '[...]/pkl/pkl-executor/build/classes/kotlin/main'
// specified for property 'compileKotlinOutputClasses' does not exist.
layout.buildDirectory.dir("classes/kotlin/main").get().asFile.mkdirs()
val workAroundKotlinGradlePluginBug by
tasks.registering {
doLast {
// Works around this problem, which sporadically appears and disappears in different
// subprojects:
// A problem was found with the configuration of task ':pkl-executor:compileJava' (type
// 'JavaCompile').
// > Directory '[...]/pkl/pkl-executor/build/classes/kotlin/main'
// specified for property 'compileKotlinOutputClasses' does not exist.
layout.buildDirectory.dir("classes/kotlin/main").get().asFile.mkdirs()
}
}
}
val truffleJavacArgs =
listOf(
// TODO: determine correct limits for Truffle specializations
// (see https://graalvm.slack.com/archives/CNQSB2DHD/p1712380902746829)
"-Atruffle.dsl.SuppressWarnings=truffle-limit"
)
tasks.compileJava {
javaCompiler = info.javaCompiler
dependsOn(workAroundKotlinGradlePluginBug)
// TODO: determine correct limits for Truffle specializations
// (see https://graalvm.slack.com/archives/CNQSB2DHD/p1712380902746829)
options.compilerArgs.add("-Atruffle.dsl.SuppressWarnings=truffle-limit")
options.compilerArgs.addAll(truffleJavacArgs + info.jpmsAddModulesFlags)
}
tasks.withType<JavaCompile>().configureEach {
javaCompiler = info.javaCompiler
options.release = info.jvmTarget
}
tasks.withType<JavaExec>().configureEach { jvmArgs(info.jpmsAddModulesFlags) }
fun Test.configureJdkTestTask(launcher: Provider<JavaLauncher>) {
useJUnitPlatform()
javaLauncher = launcher
systemProperties.putAll(info.testProperties)
jvmArgs.addAll(info.jpmsAddModulesFlags)
}
tasks.test { configureJdkTestTask(info.javaTestLauncher) }
// Prepare test tasks for each JDK version which is within the test target suite for Pkl. Each task
// uses a pinned JDK toolchain version, and is named for the major version which is tested.
//
// Test tasks configured in this manner are executed manually by name, e.g. `./gradlew testJdk11`,
// and automatically as dependencies of `check`.
//
// We omit the current JDK from this list because it is already tested, in effect, by the default
// `test` task.
//
// Pkl subprojects may elect to further configure these tasks as needed; by default, each task
// inherits the configuration of the default `test` task (aside from an overridden launcher).
val jdkTestTasks = info.multiJdkTestingWith(tasks.test) { (_, jdk) -> configureJdkTestTask(jdk) }
tasks.check { dependsOn(jdkTestTasks) }

View File

@@ -1,11 +1,29 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.gradle.accessors.dm.LibrariesForLibs
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
plugins {
id("pklJavaLibrary")
kotlin("jvm")
}
// Build configuration.
val buildInfo = project.extensions.getByType<BuildInfo>()
// Version Catalog library symbols.
@@ -24,10 +42,10 @@ tasks.compileKotlin {
enabled = true // disabled by pklJavaLibrary
}
spotless {
kotlin {
ktfmt(libs.versions.ktfmt.get()).googleStyle()
targetExclude("**/generated/**", "**/build/**")
licenseHeaderFile(rootProject.file("buildSrc/src/main/resources/license-header.star-block.txt"))
tasks.withType<KotlinJvmCompile>().configureEach {
compilerOptions {
languageVersion = KotlinVersion.KOTLIN_2_1
jvmTarget = JvmTarget.fromTarget(buildInfo.jvmTarget.toString())
freeCompilerArgs.addAll("-Xjdk-release=${buildInfo.jvmTarget}")
}
}

View File

@@ -1,19 +1,39 @@
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.net.URI
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
plugins {
`jvm-test-suite`
kotlin("jvm")
}
val buildInfo = project.extensions.getByType<BuildInfo>()
dependencies {
testImplementation(buildInfo.libs.findLibrary("assertj").get())
testImplementation(buildInfo.libs.findLibrary("junitApi").get())
testImplementation(buildInfo.libs.findLibrary("junitParams").get())
testImplementation(buildInfo.libs.findLibrary("kotlinStdLib").get())
val libs = the<LibrariesForLibs>()
testRuntimeOnly(buildInfo.libs.findLibrary("junitEngine").get())
dependencies {
testImplementation(libs.assertj)
testImplementation(libs.junitApi)
testImplementation(libs.junitParams)
testImplementation(libs.kotlinStdLib)
testRuntimeOnly(libs.junitEngine)
testRuntimeOnly(libs.junitLauncher)
}
tasks.withType<Test>().configureEach {
@@ -24,34 +44,36 @@ tasks.withType<Test>().configureEach {
// enable checking of stdlib return types
systemProperty("org.pkl.testMode", "true")
reports.named("html") {
enabled = true
}
reports.named("html") { enabled = true }
testLogging {
exceptionFormat = TestExceptionFormat.FULL
}
testLogging { exceptionFormat = TestExceptionFormat.FULL }
addTestListener(object : TestListener {
override fun beforeSuite(suite: TestDescriptor) {}
override fun beforeTest(testDescriptor: TestDescriptor) {}
override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {}
addTestListener(
object : TestListener {
override fun beforeSuite(suite: TestDescriptor) {}
// print report link at end of task, not just at end of build
override fun afterSuite(descriptor: TestDescriptor, result: TestResult) {
if (descriptor.parent != null) return // only interested in overall result
override fun beforeTest(testDescriptor: TestDescriptor) {}
if (result.resultType == TestResult.ResultType.FAILURE) {
println("\nThere were failing tests. See the report at: ${fixFileUri(testTask.reports.html.entryPoint.toURI())}")
override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {}
// print report link at end of task, not just at end of build
override fun afterSuite(descriptor: TestDescriptor, result: TestResult) {
if (descriptor.parent != null) return // only interested in overall result
if (result.resultType == TestResult.ResultType.FAILURE) {
println(
"\nThere were failing tests. See the report at: ${fixFileUri(testTask.reports.html.entryPoint.toURI())}"
)
}
}
// makes links clickable on macOS
private fun fixFileUri(uri: URI): URI {
if ("file" == uri.scheme && !uri.schemeSpecificPart.startsWith("//")) {
return URI.create("file://" + uri.schemeSpecificPart)
}
return uri
}
}
// makes links clickable on macOS
private fun fixFileUri(uri: URI): URI {
if ("file" == uri.scheme && !uri.schemeSpecificPart.startsWith("//")) {
return URI.create("file://" + uri.schemeSpecificPart)
}
return uri
}
})
)
}

View File

@@ -1,11 +0,0 @@
val assembleNative by tasks.registering {}
val testNative by tasks.registering {}
val checkNative by tasks.registering {
dependsOn(testNative)
}
val buildNative by tasks.registering {
dependsOn(assembleNative, checkNative)
}

View File

@@ -0,0 +1,341 @@
/*
* 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 java.lang.Runtime.Version
import kotlin.io.path.createDirectories
import kotlin.io.path.writeText
import org.gradle.accessors.dm.LibrariesForLibs
plugins {
id("pklGraalVm")
id("pklJavaLibrary")
id("pklNativeLifecycle")
id("pklPublishLibrary")
id("com.gradleup.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
val nativeImageClasspath by
configurations.creating {
extendsFrom(configurations.runtimeClasspath.get())
// Ensure native-image version uses GraalVM C SDKs instead of Java FFI or JNA
// (comes from artifact `mordant-jvm-graal-ffi`).
exclude("com.github.ajalt.mordant", "mordant-jvm-ffm")
exclude("com.github.ajalt.mordant", "mordant-jvm-ffm-jvm")
exclude("com.github.ajalt.mordant", "mordant-jvm-jna")
exclude("com.github.ajalt.mordant", "mordant-jvm-jna-jvm")
}
val libs = the<LibrariesForLibs>()
dependencies {
fun executableFile(suffix: String) =
files(
layout.buildDirectory.dir("executable").map { dir ->
dir.file(executableSpec.name.map { "$it-$suffix" })
}
)
nativeImageClasspath(libs.truffleRuntime)
nativeImageClasspath(libs.graalSdk)
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(nativeImageClasspath)
}
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()
}
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")
}
}
}
val requiredGlibcVersion: Version = Version.parse("2.17")
val checkGlibc by
tasks.registering {
enabled = buildInfo.os.isLinux && !buildInfo.musl
dependsOn(assembleNative)
doLast {
val exec =
providers.exec {
commandLine("objdump", "-T", assembleNative.get().outputs.files.singleFile)
}
val output = exec.standardOutput.asText.get()
val minimumGlibcVersion =
output
.split("\n")
.mapNotNull { line ->
val match = Regex("GLIBC_([.0-9]*)").find(line)
match?.groups[1]?.let { Version.parse(it.value) }
}
.maxOrNull()
if (minimumGlibcVersion == null) {
throw GradleException(
"Could not determine glibc version from executable. objdump output: $output"
)
}
if (minimumGlibcVersion > requiredGlibcVersion) {
throw GradleException(
"Incorrect glibc version. Found: $minimumGlibcVersion, required: $requiredGlibcVersion"
)
}
}
}
// 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, checkGlibc) }
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,128 @@
/*
* 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)
}
else -> {
doLast {
throw GradleException(
"Cannot build targeting ${buildInfo.os.name}/${buildInfo.targetArch} with musl=${buildInfo.musl}"
)
}
}
}
}
val testNative by
tasks.registering {
group = "verification"
dependsOn(assembleNative)
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)
}
else -> {
doLast {
throw GradleException(
"Cannot build targeting ${buildInfo.os.name}/${buildInfo.targetArch} with musl=${buildInfo.musl}"
)
}
}
}
}
val checkNative by
tasks.registering {
group = "verification"
dependsOn(testNative)
}
val buildNative by
tasks.registering {
group = "build"
dependsOn(checkNative)
}

View File

@@ -1,7 +1,18 @@
import org.gradle.api.publish.maven.tasks.GenerateMavenPom
import java.nio.charset.StandardCharsets
import java.util.Base64
/*
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
plugins {
`maven-publish`
signing
@@ -10,118 +21,16 @@ plugins {
publishing {
publications {
components.findByName("java")?.let { javaComponent ->
create<MavenPublication>("library") {
from(javaComponent)
}
}
withType<MavenPublication>().configureEach {
pom {
name.set(artifactId)
licenses {
license {
name.set("The Apache Software License, Version 2.0")
url.set("https://github.com/apple/pkl/blob/main/LICENSE.txt")
}
}
developers {
developer {
id.set("pkl-authors")
name.set("The Pkl Authors")
email.set("pkl-oss@group.apple.com")
}
}
scm {
connection.set("scm:git:git://github.com/apple/pkl.git")
developerConnection.set("scm:git:ssh://github.com/apple/pkl.git")
val buildInfo = project.extensions.getByType<BuildInfo>()
url.set("https://github.com/apple/pkl/tree/${buildInfo.commitish}")
}
issueManagement {
system.set("GitHub Issues")
url.set("https://github.com/apple/pkl/issues")
}
ciManagement {
system.set("Circle CI")
url.set("https://app.circleci.com/pipelines/github/apple/pkl")
}
}
create<MavenPublication>("library") { from(javaComponent) }
}
}
}
val validatePom by tasks.registering {
if (tasks.findByName("generatePomFileForLibraryPublication") == null) {
return@registering
}
val generatePomFileForLibraryPublication by tasks.existing(GenerateMavenPom::class)
val outputFile = layout.buildDirectory.file("validatePom") // dummy output to satisfy up-to-date check
configurePklPomMetadata()
dependsOn(generatePomFileForLibraryPublication)
inputs.file(generatePomFileForLibraryPublication.get().destination)
outputs.file(outputFile)
configurePomValidation()
doLast {
outputFile.get().asFile.delete()
val pomFile = generatePomFileForLibraryPublication.get().destination
assert(pomFile.exists())
val text = pomFile.readText()
run {
val unresolvedVersion = Regex("<version>.*[+,()\\[\\]].*</version>")
val matches = unresolvedVersion.findAll(text).toList()
if (matches.isNotEmpty()) {
throw GradleException(
"""
Found unresolved version selector(s) in generated POM:
${matches.joinToString("\n") { it.groupValues[0] }}
""".trimIndent()
)
}
}
val buildInfo = project.extensions.getByType<BuildInfo>()
if (buildInfo.isReleaseBuild) {
val snapshotVersion = Regex("<version>.*-SNAPSHOT</version>")
val matches = snapshotVersion.findAll(text).toList()
if (matches.isNotEmpty()) {
throw GradleException(
"""
Found snapshot version(s) in generated POM of Pkl release version:
${matches.joinToString("\n") { it.groupValues[0] }}
""".trimIndent()
)
}
}
outputFile.get().asFile.writeText("OK")
}
}
tasks.publish {
dependsOn(validatePom)
}
// Workaround for maven publish plugin not setting up dependencies correctly.
// Taken from https://github.com/gradle/gradle/issues/26091#issuecomment-1798137734
val dependsOnTasks = mutableListOf<String>()
tasks.withType<AbstractPublishToMaven>().configureEach {
dependsOnTasks.add(name.replace("publish", "sign").replaceAfter("Publication", ""))
dependsOn(dependsOnTasks)
}
signing {
// provided as env vars `ORG_GRADLE_PROJECT_signingKey` and `ORG_GRADLE_PROJECT_signingPassword`
// in CI.
val signingKey = (findProperty("signingKey") as String?)
?.let { Base64.getDecoder().decode(it).toString(StandardCharsets.US_ASCII) }
val signingPassword = findProperty("signingPassword") as String?
if (signingKey != null && signingPassword != null) {
useInMemoryPgpKeys(signingKey, signingPassword)
}
publishing.publications.findByName("library")?.let { sign(it) }
}
configurePklSigning()
artifacts {
project.tasks.findByName("javadocJar")?.let { archives(it) }

View File

@@ -0,0 +1,39 @@
/*
* 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.
*/
plugins { id("com.diffplug.spotless") }
val pklFormatter by configurations.creating
dependencies { pklFormatter(rootProject.project("pkl-formatter")) }
spotless {
format("pkl") {
target("**/*.pkl")
addStep(PklFormatterStep(pklFormatter).create())
licenseHeaderFile(
rootProject.file("buildSrc/src/main/resources/license-header.line-comment.txt"),
"/// ",
)
// disable ratcheting for Pkl sources
// make any change to pkl-formatter reformat the stdlib
ratchetFrom = null
}
}
for (taskName in
listOf("spotlessPkl", "spotlessPklApply", "spotlessPklCheck", "spotlessPklDiagnose")) {
tasks.named(taskName) { dependsOn(":pkl-formatter:assemble") }
}

View File

@@ -1,5 +1,5 @@
//===----------------------------------------------------------------------===//
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
// Copyright © $YEAR Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/**
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
/*
* Copyright © $YEAR Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,6 +1,6 @@
name: main
title: Main Project
version: 0.26.0-dev
version: 0.31.0-dev
prerelease: true
nav:
- nav.adoc

View File

@@ -1,3 +1,18 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
plugins {
@@ -12,10 +27,7 @@ sourceSets {
srcDir(file("modules/pkl-config-java/examples"))
srcDir(file("modules/java-binding/examples"))
}
val kotlin = project.extensions
.getByType<KotlinJvmProjectExtension>()
.sourceSets[name]
.kotlin
val kotlin = project.extensions.getByType<KotlinJvmProjectExtension>().sourceSets[name].kotlin
kotlin.srcDir(file("modules/kotlin-binding/examples"))
}
}
@@ -25,12 +37,13 @@ dependencies {
testImplementation(projects.pklConfigJava)
testImplementation(projects.pklConfigKotlin)
testImplementation(projects.pklCommonsTest)
testImplementation(projects.pklParser)
testImplementation(libs.junitEngine)
testImplementation(libs.antlrRuntime)
}
tasks.test {
inputs.files(fileTree("modules").matching {
include("**/pages/*.adoc")
}).withPropertyName("asciiDocFiles").withPathSensitivity(PathSensitivity.RELATIVE)
inputs
.files(fileTree("modules").matching { include("**/pages/*.adoc") })
.withPropertyName("asciiDocFiles")
.withPathSensitivity(PathSensitivity.RELATIVE)
}

View File

@@ -1,36 +1,61 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.tunnelvisionlabs:antlr4-runtime:4.9.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
io.leangen.geantyref:geantyref:1.3.15=testRuntimeClasspath
net.bytebuddy:byte-buddy:1.14.16=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
org.assertj:assertj-core:3.26.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.graalvm.sdk:graal-sdk:23.0.2=testRuntimeClasspath
org.graalvm.truffle:truffle-api:23.0.2=testRuntimeClasspath
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.7.10=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-reflect:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-script-runtime:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.7.10=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains:annotations:13.0=kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-api:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-engine:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.jupiter:junit-jupiter-params:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.platform:junit-platform-commons:1.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit.platform:junit-platform-engine:1.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.junit:junit-bom:5.10.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
com.github.ben-manes.caffeine:caffeine:2.9.3=swiftExportClasspathResolvable
com.google.errorprone:error_prone_annotations:2.28.0=swiftExportClasspathResolvable
io.github.java-diff-utils:java-diff-utils:4.12=kotlinInternalAbiValidation
io.leangen.geantyref:geantyref:1.3.16=testRuntimeClasspath
io.opentelemetry:opentelemetry-api:1.41.0=swiftExportClasspathResolvable
io.opentelemetry:opentelemetry-context:1.41.0=swiftExportClasspathResolvable
net.bytebuddy:byte-buddy:1.17.7=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata
org.assertj:assertj-core:3.27.6=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.bouncycastle:bcpg-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.bouncycastle:bcpkix-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.bouncycastle:bcprov-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.bouncycastle:bcutil-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.checkerframework:checker-qual:3.43.0=swiftExportClasspathResolvable
org.graalvm.polyglot:polyglot:25.0.0=testRuntimeClasspath
org.graalvm.sdk:collections:25.0.0=testRuntimeClasspath
org.graalvm.sdk:graal-sdk:25.0.0=testRuntimeClasspath
org.graalvm.sdk:nativeimage:25.0.0=testRuntimeClasspath
org.graalvm.sdk:word:25.0.0=testRuntimeClasspath
org.graalvm.truffle:truffle-api:25.0.0=testRuntimeClasspath
org.jetbrains.kotlin:abi-tools-api:2.2.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:abi-tools:2.2.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:kotlin-build-tools-api:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-compiler-runner:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-client:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:2.2.20=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-metadata-jvm:2.2.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:kotlin-native-prebuilt:2.0.21=kotlinNativeBundleConfiguration
org.jetbrains.kotlin:kotlin-reflect:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-script-runtime:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-scripting-common:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-scripting-jvm:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.20=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.jetbrains.kotlin:swift-export-embeddable:2.2.20=swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.3=swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.3=swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3=swiftExportClasspathResolvable
org.jetbrains:annotations:13.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable,testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-api:5.14.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:5.14.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.14.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.platform:junit-platform-commons:1.14.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.platform:junit-platform-engine:1.14.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.junit.platform:junit-platform-launcher:1.14.0=testRuntimeClasspath
org.junit:junit-bom:5.14.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.msgpack:msgpack-core:0.9.8=testRuntimeClasspath
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
org.organicdesign:Paguro:3.10.3=testRuntimeClasspath
org.snakeyaml:snakeyaml-engine:2.5=testRuntimeClasspath
empty=annotationProcessor,apiDependenciesMetadata,archives,compile,compileClasspath,compileOnly,compileOnlyDependenciesMetadata,default,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,runtime,runtimeClasspath,runtimeOnlyDependenciesMetadata,testAnnotationProcessor,testApiDependenciesMetadata,testCompile,testCompileOnly,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDef,testKotlinScriptDefExtensions,testRuntime
org.snakeyaml:snakeyaml-engine:2.10=testRuntimeClasspath
empty=annotationProcessor,apiDependenciesMetadata,compileClasspath,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,runtimeClasspath,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions

View File

@@ -0,0 +1,20 @@
= Evolution and Roadmap
:uri-pkl-roadmap: https://github.com/orgs/apple/projects/12/views/1
:uri-pkl-evolution: https://github.com/apple/pkl-evolution
== Evolution
Sometimes, a change to Pkl is large enough that it makes sense to create a proposal for the change so that it can be discussed in detail and vetted.
Pkl has a process for managing such designs in a repository called {uri-pkl-evolution}[Pkl Evolution].
== Roadmap
To discover what might be coming in future versions, reference the {uri-pkl-roadmap}[Pkl Roadmap] project on GitHub.
The roadmap describes estimates.
The Pkl team aims to cut a release in February, June, and October of each year.
If an item is not complete by the release cutoff date, the roadmap item may be bumped to the next release.
Additionally, as priorities change, it is possible that items can be moved around or backlogged.

View File

@@ -3,7 +3,7 @@
// the following attributes must be updated immediately before a release
// pkl version corresponding to current git commit without -dev suffix or git hash
:pkl-version-no-suffix: 0.26.0
:pkl-version-no-suffix: 0.31.0
// 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:
@@ -23,9 +23,9 @@ endif::[]
:uri-maven-docsite: https://central.sonatype.com
:uri-sonatype: https://s01.oss.sonatype.org/content/groups/public
:uri-snapshot-repo: https://central.sonatype.com/repository/maven-snapshots
:uri-maven-repo: https://s01.oss.sonatype.org/content/groups/public
:uri-maven-repo: https://central.sonatype.com/repository/maven-snapshots
ifdef::is-release-version[]
:uri-maven-repo: https://repo1.maven.org/maven2
endif::[]
@@ -68,15 +68,24 @@ endif::[]
:uri-pkldoc-example: {uri-pkl-examples-tree}/pkldoc
:uri-stdlib-baseModule: {uri-pkl-stdlib-docs}/base
:uri-stdlib-analyzeModule: {uri-pkl-stdlib-docs}/analyze
:uri-stdlib-jsonnetModule: {uri-pkl-stdlib-docs}/jsonnet
:uri-stdlib-reflectModule: {uri-pkl-stdlib-docs}/reflect
:uri-stdlib-mathModule: {uri-pkl-stdlib-docs}/math
:uri-stdlib-xmlModule: {uri-pkl-stdlib-docs}/xml
:uri-stdlib-protobufModule: {uri-pkl-stdlib-docs}/protobuf
:uri-stdlib-pklbinaryModule: {uri-pkl-stdlib-docs}/pklbinary
:uri-stdlib-yamlModule: {uri-pkl-stdlib-docs}/yaml
:uri-stdlib-YamlParser: {uri-stdlib-yamlModule}/Parser
:uri-stdlib-evaluatorSettingsModule: {uri-pkl-stdlib-docs}/EvaluatorSettings
:uri-stdlib-evaluatorSettingsHttpClass: {uri-stdlib-evaluatorSettingsModule}/Http
:uri-stdlib-Boolean: {uri-stdlib-baseModule}/Boolean
:uri-stdlib-xor: {uri-stdlib-baseModule}/Boolean#xor()
:uri-stdlib-implies: {uri-stdlib-baseModule}/Boolean#implies()
:uri-stdlib-Any: {uri-stdlib-baseModule}/Any
:uri-stdlib-String: {uri-stdlib-baseModule}/String
:uri-stdlib-Collection: {uri-stdlib-baseModule}/Collection
:uri-stdlib-StringToInt: {uri-stdlib-baseModule}/String#toInt()
:uri-stdlib-Int: {uri-stdlib-baseModule}/Int
:uri-stdlib-Float: {uri-stdlib-baseModule}/Float
:uri-stdlib-Number: {uri-stdlib-baseModule}/Number
@@ -124,7 +133,10 @@ endif::[]
:uri-stdlib-Class: {uri-stdlib-baseModule}/Class
:uri-stdlib-TypeAlias: {uri-stdlib-baseModule}/TypeAlias
:uri-stdlib-Deprecated: {uri-stdlib-baseModule}/Deprecated
:uri-stdlib-BaseValueRenderer: {uri-stdlib-baseModule}/BaseValueRenderer
:uri-stdlib-ValueRenderer: {uri-stdlib-baseModule}/ValueRenderer
:uri-stdlib-BytesRenderer: {uri-stdlib-baseModule}/BytesRenderer
:uri-stdlib-YamlRenderer: {uri-stdlib-baseModule}/YamlRenderer
:uri-stdlib-PcfRenderer-converters: {uri-stdlib-baseModule}/PcfRenderer#converters
:uri-stdlib-Function: {uri-stdlib-baseModule}/Function
:uri-stdlib-Function0: {uri-stdlib-baseModule}/Function0
@@ -134,8 +146,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

@@ -1,9 +1,15 @@
= Pkl Binary Encoding
= `pkl-binary` Encoding
include::ROOT:partial$component-attributes.adoc[]
include::partial$component-attributes.adoc[]
Pkl values can be encoded into a binary format.
This format is used for Pkl's non-JVM language bindings, for example, for its Go and Swift bindings.
:uri-pkl-core-Evaluator: {uri-pkl-core-main-sources}/Evaluator.java
Pkl values can be encoded into a binary format called "pkl-binary".
This format is a lossless serialization of the underlying Pkl values.
Pkl code can be rendered into this format using the {uri-stdlib-pklbinaryModule}[pkl:pklbinary] standard library module.
Alternatively, many language bindings also provide methods to evaluate into `pkl-binary`, such as the `evaluateExpressionPklBinary` method in link:{uri-pkl-core-Evaluator}[org.pkl.core.Evaluator].
The binary format is uses link:{uri-messagepack}[MessagePack] encoding.
@@ -36,7 +42,9 @@ For example, value `8` gets encoded as MessagePack `int8` format.
== Non-primitives
All non-primitive values are encoded as MessagePack arrays.
The first slot of the array designates the value's type. The remaining slots have fixed meanings depending on the type.
The first slot of the array designates the value's type.
The remaining slots have fixed meanings depending on the type.
Additional slots may be added to types in future Pkl releases. Decoders *must* be designed to defensively discard values beyond the number of known slots for a type or provide meaningful error messages.
The array's length is the number of slots that are filled. For example, xref:{uri-stdlib-List}[List] is encoded as an MessagePack array with two elements.
@@ -46,16 +54,16 @@ The array's length is the number of slots that are filled. For example, xref:{ur
||code |type |description |type |description |type |description
|link:{uri-stdlib-Typed}[Typed], link:{uri-stdlib-Dynamic}[Dynamic]
|`0x1`
|`0x01`
|link:{uri-messagepack-str}[str]
|Fully qualified class name
|<<type-name-encoding,Class name>>
|link:{uri-messagepack-str}[str]
|Enclosing module URI
|link:{uri-messagepack-array}[array]
|Array of <<object-members,object members>>
|link:{uri-stdlib-Map}[Map]
|`0x2`
|`0x02`
|link:{uri-messagepack-map}[map]
|Map of `<value>` to `<value>`
|
@@ -64,7 +72,7 @@ The array's length is the number of slots that are filled. For example, xref:{ur
|
|link:{uri-stdlib-Mapping}[Mapping]
|`0x3`
|`0x03`
|link:{uri-messagepack-map}[map]
|Map of `<value>` to `<value>`
|
@@ -73,7 +81,7 @@ The array's length is the number of slots that are filled. For example, xref:{ur
|
|link:{uri-stdlib-List}[List]
|`0x4`
|`0x04`
|link:{uri-messagepack-array}[array]
|Array of `<value>`
|
@@ -82,7 +90,7 @@ The array's length is the number of slots that are filled. For example, xref:{ur
|
|link:{uri-stdlib-Listing}[Listing]
|`0x5`
|`0x05`
|link:{uri-messagepack-array}[array]
|Array of `<value>`
|
@@ -91,7 +99,7 @@ The array's length is the number of slots that are filled. For example, xref:{ur
|
|link:{uri-stdlib-Set}[Set]
|`0x6`
|`0x06`
|link:{uri-messagepack-array}[array]
|Array of `<value>`
|
@@ -100,7 +108,7 @@ The array's length is the number of slots that are filled. For example, xref:{ur
|
|link:{uri-stdlib-Duration}[Duration]
|`0x7`
|`0x07`
|{uri-messagepack-float}[float64]
|Duration value
|link:{uri-messagepack-str}[str]
@@ -109,7 +117,7 @@ The array's length is the number of slots that are filled. For example, xref:{ur
|
|link:{uri-stdlib-DataSize}[DataSize]
|`0x8`
|`0x08`
|link:{uri-messagepack-float}[float64]
|Value (float64)
|link:{uri-messagepack-str}[str]
@@ -118,7 +126,7 @@ The array's length is the number of slots that are filled. For example, xref:{ur
|
|link:{uri-stdlib-Pair}[Pair]
|`0x9`
|`0x09`
|`<value>`
|First value
|`<value>`
@@ -127,7 +135,7 @@ The array's length is the number of slots that are filled. For example, xref:{ur
|
|link:{uri-stdlib-IntSeq}[IntSeq]
|`0xA`
|`0x0A`
|link:{uri-messagepack-int}[int]
|Start
|link:{uri-messagepack-int}[int]
@@ -136,7 +144,7 @@ The array's length is the number of slots that are filled. For example, xref:{ur
|Step
|link:{uri-stdlib-Regex}[Regex]
|`0xB`
|`0x0B`
|link:{uri-messagepack-str}[str]
|Regex string representation
|
@@ -145,7 +153,25 @@ The array's length is the number of slots that are filled. For example, xref:{ur
|
|link:{uri-stdlib-Class}[Class]
|`0xC`
|`0x0C`
|link:{uri-messagepack-str}[str]
|<<type-name-encoding,Class name>>
|link:{uri-messagepack-str}[str]
|Module URI
|
|
|link:{uri-stdlib-TypeAlias}[TypeAlias]
|`0x0D`
|link:{uri-messagepack-str}[str]
|<<type-name-encoding,TypeAlias name>>
|link:{uri-messagepack-str}[str]
|Module URI
|
|
|link:{uri-stdlib-Function}[Function]
|`0x0E`
|
|
|
@@ -153,16 +179,29 @@ The array's length is the number of slots that are filled. For example, xref:{ur
|
|
|link:{uri-stdlib-TypeAlias}[TypeAlias]
|`0xD`
|
|
|link:{uri-stdlib-Bytes}[Bytes]
|`0x0F`
|link:{uri-messagepack-bin}[bin]
|Binary contents
|
|
|
|
|===
[[type-name-encoding]]
[NOTE]
====
Type names have specific encoding rules:
* When the module URI is `pkl:base`:
** If the type name is `ModuleClass`, this type represents the module class of `pkl:base`.
** Otherwise, the type name corresponds to a type in `pkl:base`.
* For all other module URIs:
** When the type name contains `\#`, the string after the `#` character corresponds to a type in that module. The string before the `#` is the name of the module.
** Otherwise, the type name is the name of the module and represents the class of the module.
====
[[object-members]]
== Object Members
@@ -194,4 +233,3 @@ Like non-primitive values, object members are encoded as MessagePack arrays, whe
|`<value>`
|element value
|===

View File

@@ -9,8 +9,8 @@ The first element of the array is a code that designates the message's type, enc
The second element of the array is the message body, encoded as a map.
Messages are passed between the _client_ and the _server_.
The _client_ is the host language (for example, the Swift application when using pkl-swift).
The _server_ is the entity that provides controls for interacting with Pkl.
When hosting Pkl (for example, the Swift application when using pkl-swift), the _client_ is the host program and the _server_ is the entity that provides controls for interacting with Pkl.
When implementing an xref:language-reference:index.adoc#external-readers[external reader], the _client_ is the external reader process and the _server_ is the Pkl evaluator.
For example, in JSON representation:
@@ -75,7 +75,7 @@ requestId: Int
/// API version of the CLI's `--allowed-modules` flag
allowedModules: Listing<String>?
/// Regex patterns to dettermine which resources are allowed to be read.
/// Regex patterns to determine which resources are allowed to be read.
///
/// API version of the CLI's `--allowed-resources` flag
allowedResources: Listing<String>?
@@ -130,7 +130,7 @@ class ClientResourceReader {
/// The URI scheme this reader is responsible for reading.
scheme: String
/// Tells whether the path part of ths URI has a
/// Tells whether the path part of this URI has a
/// [hier-part](https://datatracker.ietf.org/doc/html/rfc3986#section-3).
///
/// An example of a hierarchical URI is `file:///path/to/my/file`, where
@@ -148,7 +148,7 @@ class ClientModuleReader {
/// The URI scheme this reader is responsible for reading.
scheme: String
/// Tells whether the path part of ths URI has a
/// Tells whether the path part of this URI has a
/// [hier-part](https://datatracker.ietf.org/doc/html/rfc3986#section-3).
///
/// An example of a hierarchical URI is `file:///path/to/my/file`, where
@@ -199,12 +199,17 @@ class Http {
/// PEM format certificates to trust when making HTTP requests.
///
/// If [null], Pkl will trust its own built-in certificates.
caCertificates: Binary?
caCertificates: Bytes? // <1>
/// Configuration of the HTTP proxy to use.
///
/// If [null], uses the operating system's proxy configuration.
proxy: Proxy?
/// HTTP rewrites, from source prefix to target prefix.
///
/// Each rewrite must start with `http://` or `https://`, and must end with `/`.
rewrites: Mapping<String, String>?
}
/// Settings that control how Pkl talks to HTTP proxies.
@@ -246,10 +251,8 @@ class Proxy {
/// ```
noProxy: Listing<String>(isDistinct)
}
typealias Binary = Any // <1>
----
<1> link:{uri-messagepack-bin}[bin format] (not expressable in Pkl)
<1> link:{uri-messagepack-bin}[bin format]
Example:
[source,json5]
@@ -347,14 +350,12 @@ requestId: Int
evaluatorId: Int
/// The evaluation contents, if successful.
result: Binary? // <1>
result: Bytes? // <1>
/// A message detailing why evaluation failed.
error: String?
typealias Binary = Any // <1>
----
<1> xref:binary-encoding.adoc[Pkl Binary Encoding] in link:{uri-messagepack-bin}[bin format] (not expressable in Pkl)
<1> xref:binary-encoding.adoc[Pkl Binary Encoding] in link:{uri-messagepack-bin}[bin format]
[[log]]
=== Log
@@ -414,6 +415,8 @@ The response to <<read-resource-request>>.
If successful, `contents` is set.
Otherwise, `error` is set.
If neither is set, `contents` defaults to an empty byte array.
[source,pkl]
----
/// A number identifying this request.
@@ -423,14 +426,12 @@ requestId: Int
evaluatorId: Int
/// The contents of the resource.
contents: Binary? // <1>
contents: Bytes? // <1>
/// The description of the error that occured when reading this resource.
/// The description of the error that occurred when reading this resource.
error: String?
typealias Binary = Any // <1>
----
<1> MessagePack's link:https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family[bin format family] (not expressable in Pkl)
<1> MessagePack's link:https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family[bin format family]
[[read-module-request]]
=== Read Module Request
@@ -463,6 +464,8 @@ The response to <<read-module-request>>.
If successful, `contents` is set.
Otherwise, `error` is set.
If neither is set, `contents` defaults to an empty string.
[source,pkl]
----
/// A number identifying this request.
@@ -474,7 +477,7 @@ evaluatorId: Int
/// The string contents of the module.
contents: String?
/// The description of the error that occured when reading this resource.
/// The description of the error that occurred when reading this resource.
error: String?
----
@@ -524,7 +527,7 @@ evaluatorId: Int
/// The elements at the provided base path.
pathElements: Listing<PathElement>?
/// The description of the error that occured when listing elements.
/// The description of the error that occurred when listing elements.
error: String?
class PathElement {
@@ -582,7 +585,7 @@ evaluatorId: Int
/// The elements at the provided base path.
pathElements: Listing<PathElement>?
/// The description of the error that occured when listing elements.
/// The description of the error that occurred when listing elements.
error: String?
class PathElement {
@@ -593,3 +596,96 @@ class PathElement {
isDirectory: Boolean
}
----
[[initialize-module-reader-request]]
=== Initialize Module Reader Request
Code: `0x2e` +
Type: <<server-message,Server>> <<request-message,Request>>
Initialize an xref:language-reference:index.adoc#external-readers[External Module Reader].
This message is sent to external reader processes the first time a module scheme it is registered for is read.
[source,pkl]
----
/// A number identifying this request.
requestId: Int
/// The module scheme to initialize.
scheme: String
----
[[initialize-module-reader-response]]
=== Initialize Module Reader Response
Code: `0x2f` +
Type: <<client-message,Client>> <<response-message,Response>>
Return the requested external module reader specification.
The `spec` field should be set to `null` when the external process does not implement the requested module scheme.
[source,pkl]
----
/// A number identifying this request.
requestId: Int
/// Client-side module reader spec.
///
/// Null when the external process does not implement the requested module scheme.
spec: ClientModuleReader?
----
`ClientModuleReader` is defined above by <<create-evaluator-request,Create Evaluator Request>>.
[[initialize-resource-reader-request]]
=== Initialize Resource Reader Request
Code: `0x30` +
Type: <<server-message,Server>> <<request-message,Request>>
Initialize an xref:language-reference:index.adoc#external-readers[External Resource Reader].
This message is sent to external reader processes the first time a resource scheme it is registered for is read.
[source,pkl]
----
/// A number identifying this request.
requestId: Int
/// The resource scheme to initialize.
scheme: String
----
[[initialize-resource-reader-response]]
=== Initialize Resource Reader Response
Code: `0x31` +
Type: <<client-message,Client>> <<response-message,Response>>
Return the requested external resource reader specification.
The `spec` field should be set to `null` when the external process does not implement the requested resource scheme.
[source,pkl]
----
/// A number identifying this request.
requestId: Int
/// Client-side resource reader spec.
///
/// Null when the external process does not implement the requested resource scheme.
spec: ClientResourceReader?
----
`ClientResourceReader` is defined above by <<create-evaluator-request,Create Evaluator Request>>.
[[close-external-process]]
=== Close External Process
Code: `0x32` +
Type: <<server-message,Server>> <<one-way-message,One Way>>
Initiate graceful shutdown of the external reader process.
[source,pkl]
----
/// This message has no properties.
----

View File

@@ -4,8 +4,8 @@ import org.pkl.config.java.JavaType;
import org.pkl.core.ModuleSource;
import org.junit.jupiter.api.Test;
@SuppressWarnings("unused")
// the pkl/pkl-examples repo has a similar example
@SuppressWarnings({"unused", "NewClassNamingConvention"})
// the pkl-jvm-examples repo has a similar example
public class JavaConfigExample {
@Test
public void usage() {

View File

@@ -1,6 +1,12 @@
= Java Code Generator
include::ROOT:partial$component-attributes.adoc[]
:uri-pkl-codgen-java-maven-module: {uri-maven-docsite}/artifact/org.pkl-lang/pkl-codegen-java
:uri-pkl-codegen-java-maven-module: {uri-maven-docsite}/artifact/org.pkl-lang/pkl-codegen-java
:uri-pkl-codegen-java-download: {uri-sonatype-snapshot-download}&a=pkl-cli-codegen-java&e=jar
ifdef::is-release-version[]
:uri-pkl-codegen-java-download: {github-releases}/pkl-codegen-java
endif::[]
The Java source code generator takes Pkl class definitions as an input, and generates corresponding Java classes with equally named properties.
@@ -23,11 +29,11 @@ See xref:pkl-gradle:index.adoc#installation[Installation] in the Gradle plugin c
[[install-library]]
=== Java Library
The `pkl-codegen-java` library is available {uri-pkl-codgen-java-maven-module}[from Maven Central].
The `pkl-codegen-java` library is available {uri-pkl-codegen-java-maven-module}[from Maven Central].
It requires Java 17 or higher.
ifndef::is-release-version[]
NOTE: Snapshots are published to repository `{uri-sonatype}`.
NOTE: Snapshots are published to repository `{uri-snapshot-repo}`.
endif::[]
==== Gradle
@@ -103,8 +109,41 @@ endif::[]
[[install-cli]]
=== CLI
The CLI is bundled with the Java library.
As we do not currently ship the CLI as a self-contained Jar, we recommend to provision it with a Maven compatible build tool as shown in <<install-library>>.
The CLI is available as a Java executable.
It works on multiple platforms, and requires a Java 17 (or higher) runtime on the system path.
To download:
[tabs]
====
macOS/Linux::
+
[source,shell]
[subs="+attributes"]
----
curl -L -o pkl-codegen-java '{uri-pkl-codegen-java-download}'
chmod +x pkl-codegen-java
./pkl-codegen-java --version
----
Windows::
+
[source,PowerShell]
[subs="+attributes"]
----
Invoke-WebRequest '{uri-pkl-codegen-java-download}' -OutFile pkl-codegen-java.bat
.\pkl-codegen-java --version
----
====
This should print something similar to:
[source,shell]
[subs="+attributes"]
----
pkl-codegen-java {pkl-version} (macOS 14.2, Java 17.0.10)
----
[[codegen-java-usage]]
== Usage
@@ -123,10 +162,7 @@ For more information, refer to the Javadoc documentation.
=== CLI
As explained in <<install-cli,Installation>>, the CLI is bundled with the Java library.
To run the CLI, execute the library Jar or its `org.pkl.codegen.java.Main` main class.
*Synopsis:* `java -cp <classpath> -jar pkl-codegen-java.jar [<options>] <modules>`
*Synopsis:* `pkl-codegen-java [<options>] <modules>`
`<modules>`::
The absolute or relative URIs of the modules to generate classes for.
@@ -145,23 +181,27 @@ Flag that indicates to generate private final fields and public getter methods i
[%collapsible]
====
Default: (flag not set) +
Flag that indicates to generate Javadoc based on doc comments for Pkl modules, classes, and properties.
Flag that indicates to preserve Pkl doc comments by generating corresponding Javadoc comments.
====
.--params-annotation
[%collapsible]
====
Default: `org.pkl.config.java.mapper.Named` +
Fully qualified name of the annotation to use on constructor parameters.
Default: `none` if `--generate-spring-boot` is set, `org.pkl.config.java.mapper.Named` otherwise +
Fully qualified name of the annotation type to use for annotating constructor parameters with their name. +
The specified annotation type must have a `value` parameter of type `String` or the generated code may not compile.
If set to `none`, constructor parameters are not annotated.
Whether and how constructor parameters should be annotated depends on the library that instantiates the generated classes.
For Spring Boot applications, and for users of `pkl-config-java` compiling the generated classes with `-parameters`, no annotation is required.
====
.--non-null-annotation
[%collapsible]
====
Default: `org.pkl.config.java.mapper.NonNull` +
Fully qualified named of the annotation class to use for non-null types. +
This annotation is required to have `java.lang.annotation.ElementType.TYPE_USE` as a `@Target`
or it may generate code that does not compile.
Fully qualified name of the annotation type to use for annotating non-null types. +
The specified annotation type must be annotated with `@java.lang.annotation.Target(ElementType.TYPE_USE)`
or the generated code may not compile.
====
Common code generator options:
@@ -176,4 +216,4 @@ include::../../pkl-cli/partials/cli-common-options.adoc[]
== Full Example
For a ready-to-go example with full source code,
see link:{uri-codegen-java-example}[codegen-java] in the _pkl/pkl-examples_ repository.
see link:{uri-codegen-java-example}[codegen-java] in the _pkl-jvm-examples_ repository.

View File

@@ -26,7 +26,14 @@ Flag that indicates to generate config classes for use with Spring Boot.
[%collapsible]
====
Default: (not set) +
Whether to make generated classes implement `java.io.Serializable`.
Flag that indicates to generate classes that implement `java.io.Serializable`.
====
.--add-generated-annotation
[%collapsible]
====
Default: (not set) +
Flag that indicates to add the `org.pkl.config.java.Generated` annotation to generated types.
====
.--rename

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.
@@ -118,7 +153,7 @@ Relative URIs are resolved against the working directory.
[%collapsible]
====
Default: (flag not set) +
Flag that indicates to generate Kdoc based on doc comments for Pkl modules, classes, and properties.
Flag that indicates to preserve Pkl doc comments by generating corresponding KDoc comments.
====
Common code generator options:
@@ -133,4 +168,4 @@ include::../../pkl-cli/partials/cli-common-options.adoc[]
== Full Example
For a ready-to-go example with full source code,
see link:{uri-codegen-kotlin-example}[codegen-kotlin] in the _pkl/pkl-examples_ repository.
see link:{uri-codegen-kotlin-example}[codegen-kotlin] in the _pkl-jvm-examples_ repository.

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

@@ -2,13 +2,11 @@
include::ROOT:partial$component-attributes.adoc[]
:uri-common-mark: https://commonmark.org/
:uri-newspeak: https://newspeaklanguage.org
:uri-antlr4: https://www.antlr.org
:uri-prototypical-inheritance: https://en.wikipedia.org/wiki/Prototype-based_programming
:uri-double-precision: https://en.wikipedia.org/wiki/Double-precision_floating-point_format
:uri-progressive-disclosure: https://en.wikipedia.org/wiki/Progressive_disclosure
:uri-javadoc-Pattern: https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html
:uri-github-PklLexer: {uri-github-tree}/pkl-core/src/main/antlr/PklLexer.g4
:uri-github-PklParser: {uri-github-tree}/pkl-core/src/main/antlr/PklParser.g4
:uri-github-PklLexer: {uri-github-tree}/pkl-core/src/main/java/org/pkl/core/parser/Lexer.java
:uri-pkl-core-ModuleSchema: {uri-pkl-core-main-sources}/ModuleSchema.java
:uri-pkl-core-SecurityManager: {uri-pkl-core-main-sources}/SecurityManager.java
:uri-pkl-core-ResourceReader: {uri-pkl-core-main-sources}/resource/ResourceReader.java
@@ -915,6 +913,7 @@ pigeon = new Dynamic { // <1>
==== Hidden Properties
A property with the modifier `hidden` is omitted from the rendered output and object conversions.
Hidden properties are also ignored when evaluating equality or hashing (e.g. for `Mapping` or `Map` keys).
[source,{pkl}]
----
@@ -933,12 +932,19 @@ pigeon = new Bird { // <3>
pigeonInIndex = pigeon.nameAndLifespanInIndex // <4>
pigeonDynamic = pigeon.toDynamic() // <5>
favoritePigeon = (pigeon) {
nameAndLifespanInIndex = "Bettie, \(lifespan)"
}
samePigeon = pigeon == favoritePigeon // <6>
----
<1> Properties defined as `hidden` are accessible on any `Bird` instance, but not output by default.
<2> Non-hidden properties can refer to hidden properties as usual.
<3> `pigeon` is an object with _four_ properties, but is rendered with _three_ properties.
<4> Accessing a `hidden` property from outside the class and object is like any other property.
<5> Object conversions omit hidden properties, so the resulting `Dynamic` has three properties.
<6> Objects that differ only in `hidden` property values are considered equal
Invoking Pkl on this file produces the following result.
@@ -955,6 +961,12 @@ pigeonDynamic {
lifespan = 8
nameSignWidth = 9
}
favoritePigeon {
name = "Pigeon"
lifespan = 8
nameSignWidth = 9
}
samePigeon = true
----
==== Local properties
@@ -1047,7 +1059,7 @@ class Penguin extends Bird {
<2> Error: modifier `fixed` cannot be applied to property `name`.
The `fixed` modifier is useful for defining properties that are meant to be derived from other properties.
In the following snippet, the property `result` is not meant to be assigned to, because it is derived
In the following snippet, the property `wingspanWeightRatio` is not meant to be assigned to, because it is derived
from other properties.
[source%parsed,{pkl}]
@@ -1411,7 +1423,7 @@ The recipe for transforming a listing is:
. Transform the list using ``List``'s link:{uri-stdlib-List}[rich API].
. If necessary, convert the list back to a listing.
TIP: Often, transformations happen in a link:{uri-stdlib-PcfRenderer-converters}[converter] of a link:{uri-stdlib-ValueRenderer}[value renderer].
TIP: Often, transformations happen in a link:{uri-stdlib-PcfRenderer-converters}[converter] of a link:{uri-stdlib-BaseValueRenderer}[value renderer].
Because most value renderers treat lists the same as listings, it is often not necessary to convert back to a listing.
Equipped with this knowledge, let's try to accomplish our objective:
@@ -1791,7 +1803,7 @@ The recipe for transforming a mapping is:
. Transform the map using ``Map``'s link:{uri-stdlib-Map}[rich API].
. If necessary, convert the map back to a mapping.
TIP: Often, transformations happen in a link:{uri-stdlib-PcfRenderer-converters}[converter] of a link:{uri-stdlib-ValueRenderer}[value renderer].
TIP: Often, transformations happen in a link:{uri-stdlib-PcfRenderer-converters}[converter] of a link:{uri-stdlib-BaseValueRenderer}[value renderer].
As most value renderers treat maps the same as mappings, it is often not necessary to convert back to a mapping.
Equipped with this knowledge, let's try to accomplish our objective:
@@ -1992,7 +2004,8 @@ pigeon: ParentBird = new {
[[methods]]
== Methods
Modules and classes can define methods.
Pkl methods can be defined on classes and modules using the `function` keyword.
Methods may access properties of their containing type.
Submodules and subclasses can override them.
Like Java and most other object-oriented languages, Pkl uses _single dispatch_ -- methods are dynamically dispatched based on the receiver's runtime type.
@@ -2021,6 +2034,15 @@ greeting2 = greetPigeon(parrot) // <4>
<3> Call instance method on `pigeon`.
<4> Call module method (on `this`).
Like other object-oriented languages, methods defined on extended classes and modules may be overridden.
The parent type's method may be called via the <<super-keyword,`super` keyword>>.
NOTE: Methods do not support named parameters or default parameter values.
The xref:blog:ROOT:class-as-a-function.adoc[Class-as-a-function] pattern may be a suitable replacement.
TIP: In most cases, methods without parameters should not be defined.
Instead, use <<fixed-properties,`fixed` properties>> on the module or class.
[[modules]]
== Modules
@@ -2132,6 +2154,9 @@ Optionally, the SHA-256 checksum of the package can also be specified:
Packages can be managed as dependencies within a _project_.
For more details, consult the <<projects,project>> section of the language reference.
Packages can also be downloaded from a mirror.
For more details, consult the <<mirroring_packages>> section of the language reference.
==== Standard Library URI
Example: `+pkl:math+`
@@ -2552,7 +2577,7 @@ the following security checks are performed:
* The target module URI is checked against the module allowlist (`--allowed-modules`).
* The source and target modules' _trust levels_ are determined and compared.
For access to be granted, the source module's trust level must be higher than or equal to the target module's trust level.
For access to be granted, the source module's trust level must be greater than or equal to the target module's trust level.
By default, there are five trust levels, listed from highest to lowest:
. `repl:` modules (code evaluated in the REPL)
@@ -2695,7 +2720,7 @@ quota:
disk: 20 GB
----
In addition to _type_ based converters, renderers also support _path_ based converters:
In addition to _class_-based converters, renderers also support _path_-based converters:
[source%parsed,{pkl}]
----
@@ -3156,6 +3181,7 @@ pkl: TRACE: num1 * num2 = 672 (at file:///some/module.pkl, line 42)
This section discusses language features that are generally more relevant to template and library authors than template consumers.
<<meaning-of-new,Meaning of `new`>> +
<<let-expressions,Let Expressions>> +
<<type-tests,Type Tests>> +
<<type-casts,Type Casts>> +
@@ -3171,13 +3197,174 @@ This section discusses language features that are generally more relevant to tem
<<for-generators,For Generators>> +
<<spread-syntax,Spread Syntax>> +
<<member-predicates,Member Predicates (`[[...]]`)>> +
<<this-keyword,`this` Keyword>> +
<<outer-keyword,`outer` Keyword>> +
<<super-keyword,`super` Keyword>> +
<<module-keyword,`module` Keyword>> +
<<glob-patterns,Glob Patterns>> +
<<doc-comments,Doc Comments>> +
<<name-resolution,Name Resolution>> +
<<grammar-definition,Grammar Definition>> +
<<reserved-keywords,Reserved Keywords>> +
<<blank-identifiers,Blank Identifiers>> +
<<projects,Projects>>
<<projects,Projects>> +
<<external-readers,External Readers>> +
<<mirroring_packages,Mirroring packages>>
[[meaning-of-new]]
=== Meaning of `new`
Objects in Pkl always <<amending-objects, amends>> _some_ value.
The `new` keyword is a special case of amending where a contextual value is amended.
In Pkl, there are two forms of `new` objects:
* `new` with explicit type information, for example, `new Foo {}`.
* `new` without type information, for example, `new {}`.
==== Type defaults
To understand instantiation cases without explicit parent or type information, it's important to first understand implicit default values.
When a property is declared in a module or class but is not provided an explicit default value, the property's default value becomes the type's default value.
Similarly, when `Listing` and `Mapping` types are declared with explicit type arguments for their element or value, their `default` property amends that declared type.
When `Listing` and `Mapping` types are declared without type arguments, their `default` property amends an empty `Dynamic` object.
Some types, including `Pair` and primitives like `String`, `Number`, and `Boolean` have no default value; attempting to render such a property results in the error "Tried to read property `<name>` but its value is undefined".
[source,{pkl}]
----
class Bird {
name: String = "polly"
}
bird: Bird // <1>
birdListing: Listing<Bird> // <2>
birdMapping: Mapping<String, Bird> // <3>
----
<1> Without an explicit default value, this property has default value `new Bird { name = "polly" }`
<2> With an explicit element type argument, this property's default value is equivalent to `new Listing<Bird> { default = (_) -> new Bird { name = "polly" } }`
<3> With an explicit value type argument, this property's default value is equivalent to `new Mapping<String, Bird> { default = (_) -> new Bird { name = "polly" } }`
==== Explicitly Typed `new`
Instantiating an object with `new <type>` results in a value that amends the specified type's default value.
Notably, creating a `Listing` element or assigning a `Mapping` entry value with an explicitly typed `new` ignores the object's `default` value.
[source,{pkl}]
----
class Bird {
/// The name of the bird
name: String
/// Whether this is a bird of prey or not.
isPredatory: Boolean?
}
newProperty = new Bird { // <1>
name = "Warbler"
}
someListing = new Listing<Bird> {
default {
isPredatory = true
}
new Bird { // <2>
name = "Sand Piper"
}
}
someMapping = new Mapping<String, Bird> {
default {
isPredatory = true
}
["Penguin"] = new Bird { // <3>
name = "Penguin"
}
}
----
<1> Assigning a `new` explicitly-typed value to a property.
<2> Adding an `new` explicitly-typed `Listing` element.
The value will not have property `isPredatory = true` as the `default` property of the `Listing` is not used.
<3> Assigning a `new` explicitly-typed value to a `Mapping` entry.
The value will not have property `isPredatory = true` as the `default` property of the `Mapping` is not used.
==== Implicitly Typed `new`
When using the implicitly typed `new` invocation, there is no explicit parent value to amend.
In these cases, Pkl infers the amend operation's parent value based on context:
* When assigning to a declared property, the property's default value is amended (<<amend-null, including `null`>>).
If there is no type associated with the property, an empty `Dynamic` object is amended.
* When assigning to an entry (e.g. a `Mapping` member) or element (e.g. a `Listing` member), the enclosing object's `default` property is applied to the corresponding index or key, respectively, to produce the value to be amended.
* In other cases, evaluation fails with the error message "Cannot tell which parent to amend".
The type annotation of a <<methods,method>> parameter is not used for inference.
In this case, the argument's type should be specified explicitly.
[source,{pkl}]
----
class Bird {
name: String
function listHatchlings(items: Listing<String>): Listing<String> = new {
for (item in items) {
"\(name):\(item)"
}
}
}
typedProperty: Bird = new { // <1>
name = "Swift"
}
untypedProperty = new { // <2>
hello = "world"
}
typedListing: Listing<Bird> = new {
new { // <3>
name = "Kite"
}
}
untypedListing: Listing = new {
new { // <4>
hello = "there"
}
}
typedMapping: Mapping<String, Bird> = new {
default { entryKey ->
name = entryKey
}
["Saltmarsh Sparrow"] = new { // <5>
name = "Sharp-tailed Sparrow"
}
}
amendedMapping = (typedMapping) {
["Saltmarsh Sparrow"] = new {} // <6>
}
class Aviary {
birds: Listing<Bird> = new {
new { name = "Osprey" }
}
}
aviary: Aviary = new {
birds = new { // <7>
new { name = "Kiwi" }
}
}
swiftHatchlings = typedProperty.listHatchlings(new { "Poppy"; "Chirpy" }) // <8>
----
<1> Assignment to a property with an explicitly declared type, amending `new Bird {}`.
<2> Assignment to an undeclared property in module context, amending `new Dynamic {}`.
<3> `Listing` element creation, amending implicit `default`, `new Bird {}`.
<4> `Listing` element creation, amending implicit `default`, `new Dynamic {}`.
<5> `Mapping` value assignment, amending the result of applying `default` to `"Saltmarsh Sparrow"`, `new Bird { name = "Saltmarsh Sparrow" }`.
<6> `Mapping` value assignment _replacing_ the parent's entry, amending the result of applying `default` to `"Saltmarsh Sparrow"`, `new Bird { name = "Saltmarsh Sparrow" }`.
<7> Amending the property default value `new Listing { new Bird { name = "Osprey" } }`; the result contains both birds.
<8> Error: Cannot tell which parent to amend.
[[let-expressions]]
=== Let Expressions
@@ -3200,10 +3387,11 @@ Here is an example:
[source%tested,{pkl}]
----
birdDiets = let (diets = List("Seeds", "Berries", "Mice"))
List(diets[2], diets[0]) // <1>
birdDiets =
let (diets = List("Seeds", "Berries", "Mice"))
List(diets[2], diets[0]) // <1>
----
<1> result: `List("Mice", "Seeds")`
<1> result: `birdDiets = List("Mice", "Seeds")`
`let` expressions serve two purposes:
@@ -3214,20 +3402,22 @@ List(diets[2], diets[0]) // <1>
[source%tested,{pkl}]
----
birdDiets = let (diets: List<String> = List("Seeds", "Berries", "Mice"))
diets[2] + diets[0] // <1>
birdDiets =
let (diets: List<String> = List("Seeds", "Berries", "Mice"))
diets[2] + diets[0] // <1>
----
<1> result: `List("Mice", "Seeds")`
<1> result: `birdDiets = List("Mice", "Seeds")`
`let` expressions can be stacked:
[source%tested,{pkl}]
----
birdDiets = let (birds = List("Pigeon", "Barn owl", "Parrot"))
let (diet = List("Seeds", "Mice", "Berries"))
birds.zip(diet) // <1>
birdDiets =
let (birds = List("Pigeon", "Barn owl", "Parrot"))
let (diet = List("Seeds", "Mice", "Berries"))
birds.zip(diet) // <1>
----
<1> result: `List(Pair("Pigeon", "Seeds"), Pair("Barn owl", "Mice"), Pair("Parrot", "Berries"))`
<1> result: `birdDiets = List(Pair("Pigeon", "Seeds"), Pair("Barn owl", "Mice"), Pair("Parrot", "Berries"))`
[[type-tests]]
=== Type Tests
@@ -3357,9 +3547,7 @@ res6 = list.map((n) -> n * 3) // <6>
[[sets]]
=== Sets
A value of type link:{uri-stdlib-Set}[Set] is an ordered collection of unique _elements_.
A set's elements are eagerly evaluated.
A value of type link:{uri-stdlib-Set}[Set] is a collection of unique _elements_.
Sets are constructed with the `Set()` methodfootnote:soft-keyword[]:
@@ -3375,6 +3563,20 @@ res4 = Set(1, "x", 5.min, List(1, 2, 3)) // <4>
<3> result: same set of length 3
<4> result: heterogeneous set that contains a list as its last element
Sets retain the order of elements when constructed, which impacts how they are iterated over.
However, this order is not considered when determining equality of two sets.
[source%tested,{pkl}]
----
res1 = Set(4, 3, 2)
res2 = res1.first // <1>
res3 = res1.toListing() // <2>
res4 = Set(2, 3, 4) == res1 // <3>
----
<1> result: `4`
<2> result: `new Listing { 4; 3; 2 }`
<3> result: `true`
To compute the union of sets, use the `+` operator:
[source%tested,{pkl-expr}]
@@ -3402,7 +3604,7 @@ res4 = set.intersect(Set(3, 9, 2)) // <4>
[[maps]]
=== Maps
A value of type link:{uri-stdlib-Map}[Map] is an ordered collection of _values_ indexed by _key_.
A value of type link:{uri-stdlib-Map}[Map] is a collection of _values_ indexed by _key_.
A map's key-value pairs are called its _entries_.
Keys and values are eagerly evaluated.
@@ -3437,6 +3639,20 @@ Any Pkl value can be used as a map key:
Map(new Dynamic { name = "Pigeon" }, 10.gb)
----
Maps retain the order of entries when constructed, which impacts how they are iterated over.
However, this order is not considered when determining equality of two maps.
[source%tested,{pkl}]
----
res1 = Map(2, "hello", 1, "world")
res2 = res1.entries.first // <1>
res3 = res1.toMapping() // <2>
res4 = res1 == Map(1, "world", 2, "hello") // <3>
----
<1> result: `Pair(2, "hello")`
<2> result: `new Mapping { [2] = "hello"; [1] = "world" }`
<3> result: `true`
To merge maps, use the `+` operator:
[source%tested,{pkl}]
@@ -3472,6 +3688,41 @@ res5 = map.getOrNull("Falcon") // <5>
<4> result: `2`
<5> result: `null`
[[bytes]]
=== Bytes
A value of type `Bytes` is a sequence of `UInt8` elements.
`Bytes` can be constructed by passing byte values into the constructor.
[source,pkl]
----
bytes1 = Bytes(0xff, 0x00, 0x3f) // <1>
bytes2 = Bytes() // <2>
----
<1> Result: a `Bytes` with 3 elements
<2> Result: an empty `Bytes`
`Bytes` can also be constructed from a base64-encoded string, via `base64DecodedBytes`:
[source,pkl]
----
bytes3 = "cGFycm90".base64DecodedBytes // <1>
----
<1> Result: `Bytes(112, 97, 114, 114, 111, 116)`
==== `Bytes` vs `List<UInt8>`
`Bytes` is similar to `List<UInt8>` in that they are both sequences of `UInt8` elements.
However, they are semantically distinct.
`Bytes` represent binary data, and is typically rendered differently.
For example, they are rendered as `<data>` tags when using `PListRenderer`.
`Bytes` also have different performance characteristics; a value of type `Bytes` tends to be managed as a contiguous memory block.
Thus, they are more compact and consume less memory.
However, they are not optimized for transformations.
For example, given two values of size `M` and `N`, concatenating two `Bytes` values allocates O(M + N) space, whereas concatenating two `List` values allocates O(1) space.
[[regular-expressions]]
=== Regular Expressions
@@ -3721,6 +3972,7 @@ bird2: Bird? = null // <2>
The only class types that admit `null` values despite not ending in `?` are `Any` and `Null`.
(`Null` is not very useful as a type because it _only_ admits `null` values.)
`Any?` and `Null?` are equivalent to `Any` and `Null`, respectively.
In some languages, nullable types are also known as _optional types_.
[[generic-types]]
==== Generic Types
@@ -4458,6 +4710,10 @@ The following types are iterable:
|entry key (`Key`)
|entry value (`Value`)
|`Bytes`
|element index (`Int`)
|element value (`UInt8`)
|`Listing<Element>`
|element index (`Int`)
|element value (`Element`)
@@ -4538,6 +4794,9 @@ The following table describes how different iterables turn into object members:
| `IntSeq`
| Element
| `Bytes`
| Element
|===
These types can only be spread into enclosing objects that support that member type.
@@ -4560,7 +4819,7 @@ oldPets {
}
newPets {
...cast
...oldPets
["Pigeon"] = "Toby the Pigeon" // <1>
}
----
@@ -4620,6 +4879,161 @@ The predicate, enclosed in double brackets (`\[[...]]`), is matched against each
Within the predicate, `this` refers to the member that the predicate is matched against.
Matching members are amended (`{ ... }`) or overridden (`= <new-value>`).
[[this-keyword]]
=== `this` keyword
Normally, the `this` keyword references the enclosing object's receiver.
Example:
[source,pkl]
----
bird {
eatsInsects = this is InsectavorousBird
}
----
When used inside a <<type-constraints,type constraint>>, `this` refers to the value being tested.
Example:
[source,pkl]
----
port: UInt16(this > 1000)
----
When used inside a <<member-predicates,member predicate>>, `this` refers to the value being matched against.
Example:
[source,pkl]
----
animals {
[[this is Bird]] {
canFly = true
}
}
----
[[receiver]]
==== Receiver
The receiver is the bottom-most object in the <<prototype-chain>>.
That means that, within the context of an amending object, the reciever is the amending object.
Example:
[source,pkl]
----
hidden lawyerBird {
title = "\(this.name), Esq."
}
polly = (lawyerBird) {
name = "Polly" // <1>
}
----
<1> Polly has title `"Polly, Esq."`.
[[outer-keyword]]
=== `outer` keyword
The `outer` keyword references the <<receiver,receiver>> of the immediately outer lexical object.
It can be useful to disambiguate a lookup that might otherwise resolve elsewhere.
Example:
[source%tested,pkl]
----
foo {
bar = "bar"
qux {
bar = outer.bar // <1>
}
}
----
<1> References `bar` one level higher.
Note that `outer` cannot be chained.
In order to reference a value more than one level higher, a typical pattern is to declare a local property at that level.
For example:
[source%parsed,pkl]
----
foo {
local self = this
bar {
baz {
qux = self.qux
}
}
}
----
[[super-keyword]]
=== `super` keyword
The `super` keyword references the parent object in the <<prototype-chain,prototype chain>>.
When used within a class, it refers to the superclass's prototype.
When used within an object, it refers to the parent object in the amends chain.
Example:
[source%tested,pkl]
----
bird = new { name = "Quail" }
bird2 = (bird) { name = "Ms. \(super.name)" } // <1>
abstract class Bird {
foods: Listing<String>
function canEat(food: String): Boolean = foods.contains(food)
}
class InsectavorousBird extends Bird {
function canEat(food: String) =
super.canEat(food) || food == "insect" // <2>
}
----
<1> Result: `"Ms. Quail"`
<2> Calls parent class method `canEat()`
The `super` keyword must be followed by property/method access, or subscript.
`super` by itself a syntax error; whereas `super.foo` and `super["foo"]` are valid expressions.
[[module-keyword]]
=== `module` keyword
The `module` keyword can be used as either a value, or as a type.
When used as a value, it refers to the <<receiver,receiver>> of the module itself.
[source%tested,pkl]
----
name = "Quail"
some {
deep {
object {
name = module.name // <1>
}
}
}
----
<1> Resolves to `"Quail"`
When used as a type, it is the module's class.
[source%parsed,pkl]
----
module Bird
friend: module // <1>
----
<1> Is class `Bird`
The `module` type is a _self type_.
If the module is extended by another module, the `module` type refers to the extending module when
in the context of that module.
[[glob-patterns]]
=== Glob Patterns
@@ -4706,8 +5120,8 @@ TIP: If incorporating escape characters into a glob pattern, use <<custom-string
|===
|Pattern |Description
|`*.pc[lf]`
|Anything suffixed by `.pkl`, or `.pcf`.
|`*.pk[lg]`
|Anything suffixed by `.pkl`, or `.pkg`.
|`**.y{a,}ml`
|Anything suffixed by either `yml` or `yaml`, crossing directory boundaries.
@@ -5065,11 +5479,6 @@ For example, the prototype chain of value `42` contains, now listed from top to
A prototype chain never contains a non-object value, such as `42`.
[[grammar-definition]]
=== Grammar Definition
Pkl's link:{uri-antlr4}[ANTLR 4] grammar is defined in link:{uri-github-PklLexer}[PklLexer.g4] and link:{uri-github-PklParser}[PklParser.g4].
[[reserved-keywords]]
=== Reserved keywords
@@ -5086,6 +5495,8 @@ They cannot be used as a regular identifier, and currently do not have any meani
To use these names in an identifier, <<quoted-identifiers, surround them with backticks>>.
For a complete list of keywords, consult field `Lexer.KEYWORDS` in {uri-github-PklLexer}[Lexer.java].
[[blank-identifiers]]
=== Blank Identifiers
@@ -5146,8 +5557,8 @@ It is defined by the presence of a `PklProject` file that amends the standard li
Defining a project serves the following purposes:
1. It allows defining common evaluator settings for Pkl modules within a logical project.
2. It helps with managing <<packages,package>> dependencies for Pkl modules within a logical project.
3. It enables packaging and sharing the contents of the project as a <<packages,package>>.
2. It helps with managing <<package-asset-uri,package>> dependencies for Pkl modules within a logical project.
3. It enables packaging and sharing the contents of the project as a <<package-asset-uri,package>>.
4. It allows importing packages via dependency notation.
[[project-dependencies]]
@@ -5225,7 +5636,7 @@ package {
packageZipUrl = "https://example.com/\(name)/\(name)@\(version).zip" // <4>
}
----
<1> The display name of the package. For display purposes only.
<1> The display name of the package.For display purposes only.
<2> The package URI, without the version part.
<3> The version of the package.
<4> The URL to download the package's ZIP file.
@@ -5233,8 +5644,9 @@ package {
The package itself is created by the command xref:pkl-cli:index.adoc#command-project-package[`pkl project package`].
This command only prepares artifacts to be published.
Once the artifacts are prepared, they are expected to be uploaded to an HTTPS server such that the ZIP asset can be downloaded at path `packageZipUrl`, and the metadata can be downloaded at `+https://<package uri>+`.
Once the artifacts are prepared, they are expected to be uploaded to an HTTPS server such that the ZIP asset can be downloaded at path `packageZipUrl`, and the metadata can be downloaded at `+https://<package uri>+`.
[[local-dependencies]]
==== Local dependencies
A project can depend on a local project as a dependency.
@@ -5282,3 +5694,90 @@ It can be imported using dependency notation, i.e. `import "@fruit/Pear.pkl"`.
At runtime, it will resolve to relative path `../fruit/Pear.pkl`.
When packaging projects with local dependencies, both the project and its dependent project must be passed to the xref:pkl-cli:index.adoc#command-project-package[`pkl project package`] command.
[[external-readers]]
=== External Readers
External readers are a mechanism to extend the <<modules,module>> and <<resources,resource>> URI schemes that Pkl supports.
Readers are implemented as ordinary executables and use Pkl's xref:bindings-specification:message-passing-api.adoc[message passing API] to communicate with the hosting Pkl evaluator.
The xref:swift:ROOT:index.adoc[Swift] and xref:go:ROOT:index.adoc[Go] language binding libraries provide an `ExternalReaderRuntime` type to facilitate implementing external readers.
External readers are configured separately for modules and resources.
They are registered by mapping their URI scheme to the executable to run and additional arguments to pass.
This is done on the command line by passing `--external-resource-reader` and `--external-module-reader` flags, which may both be passed multiple times.
[source,text]
----
$ pkl eval <module> --external-resource-reader <scheme>=<executable> --external-module-reader <scheme>='<executable> <argument> <argument>'
----
External readers may also be configured in a <<projects, Project's>> `PklProject` file.
[source,{pkl}]
----
evaluatorSettings {
externalResourceReaders {
["<scheme>"] {
executable = "<executable>"
}
}
externalModuleReaders {
["<scheme>"] {
executable = "<executable>"
arguments { "<arg>"; "<arg>" }
}
}
}
----
Registering an external reader for a scheme automatically adds that scheme to the default allowed modules/resources.
As with Pkl's built-in module and resource schemes, setting explicit allowed modules or resources overrides this behavior and appropriate patterns must be specified to allow use of external readers.
==== Example
Consider this module:
[source,{pkl}]
----
username = "pigeon"
email = read("ldap://ds.example.com:389/dc=example,dc=com?mail?sub?(uid=\(username))").text
----
Pkl doesn't implement the `ldap:` resource URI scheme natively, but an external reader can provide it.
Assuming a hypothetical `pkl-ldap` executable implementing the external reader protocol and the `ldap:` scheme is in the `$PATH`, this module can be evaluated as:
[source,text]
----
$ pkl eval <module> --external-resource-reader ldap=pkl-ldap
username = "pigeon"
email = "pigeon@example.com"
----
In this example, the external reader may provide both `ldap:` and `ldaps:` schemes.
To support both schemes during evaluation, both would need to be registered explicitly:
[source,text]
----
$ pkl eval <module> --external-resource-reader ldap=pkl-ldap --external-resource-reader ldaps=pkl-ldap
----
[[mirroring_packages]]
=== Mirroring packages
A package is a shareable archive of modules and resources that are published to the internet.
A package's URI tells two things:
1. The name of the package.
2. Where the package is downloaded from.
For example, given the package name `package://example.com/mypackage@1.0.0`, Pkl will make an HTTPS request to `\https://example.com/mypackage@1.0.0` to fetch package metadata.
In situations where internet access is restricted, a mirror can be set up to allow use of packages that are published to the internet.
To direct Pkl to a mirror, the `--http-rewrite` CLI option (and its equivalent options when using Pkl's other evaluator APIs) must be used.
For example, `--http-rewrite \https://pkg.pkl-lang.org/=\https://my.internal.mirror/` will tell Pkl to download packages from host `my.internal.mirror`.
NOTE: To effectively mirror packages from pkg.pkl-lang.org, there must be two rewrites; one for `\https://pkg.pkl-lang.org/` (where package metadata is downloaded), and one for `\https://github.com/` (where package zip files are downloaded).
NOTE: Pkl does not provide any tooling to run a mirror server.
To fully set up mirroring, an HTTP(s) server will need be running, and which mirrors the same assets byte-for-byte.

View File

@@ -134,6 +134,7 @@ exampleObjectWithMixedElements {
<2> Elements don't have to be literal values; they can be arbitrary _expressions_.
<3> Elements can really be _any_ value, not just primitive values.
[[entries]]
=== Entries
Objects can have one more kind of member; _entries_.

View File

@@ -213,7 +213,7 @@ adultBirdFoods {
A `.pkl` file describes a _module_.
Modules are objects that can be referred to from other modules.
Going back to the example above, you can write `parrot` as a separate module.
Going back to the example above, you can write `pigeon` as a separate module.
[source,{pkl}]
.pigeon.pkl

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
@@ -53,8 +54,7 @@ whereas, the Alpine Linux executable is statically linked against _musl libc_ an
====
The Java executable works on multiple platforms and has a smaller binary size than the native executables.
However, it requires a Java 17 (or higher) runtime on the system path, has a noticeable startup delay,
and runs complex Pkl code slower than the native executables.
However, it requires a Java 17 (or higher) runtime on the system path, and has a noticeable startup delay.
All flavors are built from the same codebase and undergo the same automated testing.
Except where noted otherwise, the rest of this page discusses the native executables.
@@ -85,6 +85,54 @@ ifndef::is-release-version[]
For instructions, switch to a release version of this page.
endif::[]
[[mise]]
=== Mise
On macOS, Linux, and Windows, release versions can be installed with {uri-mise}[Mise].
ifdef::is-release-version[]
To install Pkl, run:
[source,shell]
[subs="+attributes"]
----
# Install and activate Pkl globally
mise use -g pkl@{pkl-version}
# Install and activate Pkl locally
mise use pkl@{pkl-version}
----
endif::[]
ifndef::is-release-version[]
For instructions, switch to a release version of this page.
endif::[]
[[winget]]
=== Windows Package Manager
On Windows, release versions can be installed with {uri-winget}[Windows Package Manager].
ifdef::is-release-version[]
To install Pkl, run:
[source,shell]
----
winget install Apple.Pkl
----
To update Pkl, run:
[source,shell]
----
winget upgrade Apple.Pkl
----
endif::[]
ifndef::is-release-version[]
For instructions, switch to a release version of this page.
endif::[]
[[download]]
=== Download
@@ -201,6 +249,14 @@ NOTE: We currently do not support the aarch64 architecture for Windows.
[[java-executable]]
=== Java Executable
The Java executable is a jar that can be executed directly on macOS, Linux, and Windows.
It requires `java` to be installed, and available on `$PATH`.
[tabs]
====
macOS/Linux::
+
[source,shell]
[subs="+attributes"]
----
@@ -209,6 +265,16 @@ chmod +x jpkl
./jpkl --version
----
Windows::
+
[source,PowerShell]
[subs="+attributes"]
----
Invoke-WebRequest '{uri-pkl-java-download}' -OutFile jpkl.bat
.\jpkl --version
----
====
This should print something similar to:
[source,shell]
@@ -217,8 +283,7 @@ This should print something similar to:
Pkl {pkl-version} (macOS 14.2, Java 17.0.10)
----
NOTE: The Java executable does not work as an executable file on Windows.
However, it will work as a jar, for example, with `java -jar jpkl`.
NOTE: The Java executable is named `jpkl`.
[[usage]]
== Usage
@@ -342,7 +407,7 @@ pkl eval -m . myFiles.pkl
pkl eval -m "%{moduleName}" foo.pkl bar.pkl
----
For additional details, see xref:language-reference:index.adoc#multiple-file-output[Multiple File Output]
For additional details, see xref:language-reference:index.adoc#multiple-file-output[Multiple File Output]
in the language reference.
====
@@ -409,6 +474,10 @@ Evaluate the given `<modules>` as _tests_, producing a test report and appropria
Renderers defined in test files will be ignored by the `test` command.
Tests that result in writing `pkl-expected.pcf` files are considered failing tests.
If these are the only failures, the command exits with exit code 10.
Otherwise, failures result in exit code 1.
<modules>::
The absolute or relative URIs of the modules to test. Relative URIs are resolved against the working directory.
@@ -422,9 +491,31 @@ Default: (none) +
Example: `./build/test-results` +
Directory where to store JUnit reports.
By default, one file will be created for each test module. This behavior can be changed with `--junit-aggregate-reports`, which will instead create a single JUnit report file with all test results.
No JUnit reports will be generated if this option is not present.
====
[[junit-aggregate-reports]]
.--junit-aggregate-reports
[%collapsible]
====
Aggregate JUnit reports into a single file.
By default it will be `pkl-tests.xml` but you can override it using `--junit-aggregate-suite-name` flag.
====
[[junit-aggregate-suite-name]]
.--junit-aggregate-suite-name
[%collapsible]
====
Default: (none) +
Example: `my-tests` +
The name of the root JUnit test suite.
Used in combination with `--junit-aggregate-reports` flag.
====
[[overwrite]]
.--overwrite
[%collapsible]
@@ -512,6 +603,24 @@ Directory where to store JUnit reports.
No JUnit reports will be generated if this option is not present.
====
.--junit-aggregate-reports
[%collapsible]
====
Aggregate JUnit reports into a single file.
By default it will be `pkl-tests.xml` but you can override it using `--junit-aggregate-suite-name` flag.
====
.--junit-aggregate-suite-name
[%collapsible]
====
Default: (none) +
Example: `my-tests` +
The name of the root JUnit test suite.
Used in combination with `--junit-aggregate-reports` flag.
====
.--overwrite
[%collapsible]
====
@@ -558,17 +667,138 @@ package already exists in the cache directory, this command is a no-op.
This command accepts <<common-options,common options>>.
[[command-analyze-imports]]
=== `pkl analyze imports`
*Synopsis*: `pkl analyze imports [<modules>]`
This command builds a graph of imports declared in the provided modules.
This is a lower level command that is meant to be useful for Pkl-related tooling.
For example, this command feeds into the xref:pkl-gradle:index.adoc[] to determine if tasks are considered up-to-date or not.
This command produces an object with two properties, `imports` and `resolvedImports`.
The `imports` property is a mapping of a module's absolute URI, to the set of imports declared within that module.
The `resolvedImports` property is a mapping of a module's absolute URI (as stated in `imports`), to the resolved absolute URI that might be useful for fetching the module's contents.
For example, a xref:language-reference:index.adoc#local-dependencies[local dependency] import will have an in-language URI with scheme `projectpackage:`, and may have resolved URI with scheme `file:` (assuming that the project is file-based).
Examples:
[source,shell]
----
# Analyze the imports of a single module
pkl analyze imports myModule.pkl
# Same as the previous command, but output in JSON.
pkl analyze imports -f json myModule.pkl
# Analyze imports of all modules declared within src/
pkl analyze imports src/*.pkl
----
<modules>::
The absolute or relative URIs of the modules to analyze. Relative URIs are resolved against the working directory.
==== Options
.-f, --format
[%collapsible]
====
Same meaning as <<format>> in <<command-eval>>.
====
.-o, --output-path
[%collapsible]
====
Same meaning as <<output-path>> in <<command-eval>>.
====
This command also takes <<common-options,common options>>.
[[command-shell-completion]]
=== `pkl shell-completion`
*Synopsis*: `pkl shell-completion <shell>`
Generate shell completion script. Supported shells are: `bash`, `zsh`, `fish`.
[source,shell]
----
# Generate shell completion script for bash
pkl shell-completion bash
# Generate shell completion script for zsh
pkl shell-completion zsh
----
[[command-format]]
=== `pkl format`
*Synopsis*: `pkl format <options> [<paths>]`
This command formats or checks formatting of Pkl files. +
Exit codes:
* 0: No violations found or files were updated.
* 1: An unexpected error happened (ex.: IO error)
* 11: Violations were found (when running without `--write`).
If the path is a directory, recursively looks for files with a `.pkl` extension, or files named `PklProject`.
By default, the input files are formatted, and written to standard out.
==== Options
.--grammar-version
[%collapsible]
====
Default: `2` (latest version) +
Select the grammar compatibility version for the formatter.
New versions are created for each backward incompatible grammar change.
====
.-s, --silent
[%collapsible]
====
Skip writing to standard out. Mutually exclusive with `--diff-name-only`.
====
.-w, --write
[%collapsible]
====
Format files in place, overwriting them. Implies `--diff-name-only`.
====
.--diff-name-only
[%collapsible]
====
Write the path of files with formatting violations to stdout.
====
[[common-options]]
=== Common options
The <<command-eval>>, <<command-test>>, <<command-repl>>, <<command-project-resolve>>, <<command-project-package>>, and <<command-download-package>> commands support the following common options:
The <<command-eval>>, <<command-test>>, <<command-repl>>, <<command-project-resolve>>, <<command-project-package>>, <<command-download-package>>, and <<command-analyze-imports>> commands support the following common options:
include::../../pkl-cli/partials/cli-common-options.adoc[]
The <<command-eval>>, <<command-test>>, <<command-repl>>, and <<command-download-package>> commands also take the following options:
The <<command-eval>>, <<command-test>>, <<command-repl>>, <<command-download-package>>, and <<command-analyze-imports>> commands also take the following options:
include::../../pkl-cli/partials/cli-project-options.adoc[]
[[root-options]]
=== Root options
The root `pkl` command supports the following options:
.-v, --version
[%collapsible]
====
Display version information.
====
== Evaluating Modules
Say we have the following module:
@@ -667,8 +897,6 @@ Type :help or :examples for more information.
pkl>
----
NOTE: The Java executable is named `jpkl`.
=== Loading Modules
To load <<config.pkl,`config.pkl`>> into the REPL, run:

View File

@@ -7,7 +7,6 @@ Comma-separated list of URI patterns that determine which modules can be loaded
Patterns are matched against the beginning of module URIs.
(File paths have been converted to `file:` URLs at this stage.)
At least one pattern needs to match for a module to be loadable.
Both source modules and transitive modules are subject to this check.
====
[[allowed-resources]]
@@ -20,6 +19,19 @@ Patterns are matched against the beginning of resource URIs.
At least one pattern needs to match for a resource to be readable.
====
[[color]]
.--color
[%collapsible]
====
Default: `auto` +
When to format messages with ANSI color codes.
Possible values:
- `"never"`: Never format
- `"auto"`: Format if `stdin`, `stdout`, or `stderr` are connected to a console.
- `"always"`: Always format
====
[[cache-dir]]
.--cache-dir
[%collapsible]
@@ -97,12 +109,6 @@ Duration, in seconds, after which evaluation of a source module will be timed ou
Note that a timeout is treated the same as a program error in that any subsequent source modules will not be evaluated.
====
.-v, --version
[%collapsible]
====
Display version information.
====
.-w, --working-dir
[%collapsible]
====
@@ -140,3 +146,22 @@ 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`.
====
.--trace-mode
[%collapsible]
====
Default: `compact` +
Specifies how `trace()` output is formatted.
Possible options are `compact` and `pretty`.
====

View File

@@ -6,8 +6,8 @@ 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
@SuppressWarnings({"unchecked", "unused", "ConstantConditions"})
// the pkl-jvm-examples repo has a similar example
@SuppressWarnings({"unchecked", "unused", "ConstantConditions", "NewClassNamingConvention"})
public class CoreEvaluatorExample {
@Test
public void usage() {

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
@@ -162,7 +204,7 @@ We recommend to provision it with a Maven compatible build tool as shown in <<in
The Pkldoc tool is offered as Gradle plugin, Java library, and CLI.
It can generate documentation either for modules directly, or generate documentation for _package uris_.
The tool requires an argument of a module named `_docsite-info.pkl`, that amends link:{uri-DocsiteInfo}[pkl.DocsiteInfo].
The tool requires an argument of a module named _docsite-info.pkl_, that amends link:{uri-DocsiteInfo}[pkl.DocsiteInfo].
[discrete]
==== Generating documentation for modules directly
@@ -216,10 +258,7 @@ For more information, refer to the Javadoc documentation.
=== CLI
As mentioned in <<install-cli,CLI Installation>>, the CLI is bundled with the library.
To run the CLI, execute the library Jar or its `org.pkl.doc.Main` class.
*Synopsis:* `java -cp <classpath> -jar pkl-doc.jar [<options>] <modules>`
*Synopsis:* `pkldoc [<options>] <modules>`
`<modules>`::
The absolute or relative URIs of docsite descriptors, package descriptors, and the modules for which to generate documentation.
@@ -232,10 +271,18 @@ Relative URIs are resolved against the working directory.
[%collapsible]
====
Default: (none) +
Example: `pkldoc`
Example: `pkldoc` +
The directory where generated documentation is placed.
====
.--no-symlinks
[%collapsible]
====
Create copies of files and directories instead of symbolic links.
In particular, this affects how the "current" directories containing documentation content for the last generated version should be created.
By default, a symbolic link is created pointing to the last generated version. If symlinks are disabled, a full copy of the last generated version is created.
====
Common CLI options:
include::../../pkl-cli/partials/cli-common-options.adoc[]
@@ -244,4 +291,4 @@ include::../../pkl-cli/partials/cli-common-options.adoc[]
== Full Example
For a ready-to-go example with full source code and detailed walkthrough,
see link:{uri-pkldoc-example}[pkldoc] in the _pkl/pkl-examples_ repository.
see link:{uri-pkldoc-example}[pkldoc] in the _pkl-jvm-examples_ repository.

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:
@@ -102,7 +102,6 @@ pkl {
evaluators {
evalPkl {
sourceModules.add(file("module1.pkl"))
transitiveModules.from file("module2.pkl")
outputFile = layout.buildDirectory.file("module1.yaml")
outputFormat = "yaml"
}
@@ -118,7 +117,6 @@ pkl {
evaluators {
register("evalPkl") {
sourceModules.add(file("module1.pkl"))
transitiveModules.from(file("module2.pkl"))
outputFile.set(layout.buildDirectory.file("module1.yaml"))
outputFormat.set("yaml")
}
@@ -127,9 +125,6 @@ pkl {
----
====
To guarantee correct Gradle up-to-date behavior,
`transitiveModules` needs to contain all module files transitively referenced by `sourceModules`.
For each declared evaluator, the Pkl plugin creates an equally named task.
Hence the above evaluator can be run with:
@@ -139,7 +134,7 @@ $ ./gradlew evalPkl
----
For a ready-to-go example with full source code,
see link:{uri-build-eval-example}[codegen-java] in the _pkl/pkl-examples_ repository.
see link:{uri-build-eval-example}[codegen-java] in the _pkl-jvm-examples_ repository.
=== Configuration Options
@@ -200,7 +195,7 @@ Example 1: `multipleFileOutputDir = layout.projectDirectory.dir("output")` +
Example 2: `+multipleFileOutputDir = layout.projectDirectory.file("%{moduleDir}/output")+`
The directory where a module's output files are placed.
Setting this option causes Pkl to evaluate a module's `output.files` property
Setting this option causes Pkl to evaluate a module's `output.files` property
and write the files specified therein.
Within `output.files`, a key determines a file's path relative to `multipleFileOutputDir`,
and a value determines the file's contents.
@@ -212,7 +207,7 @@ This option cannot be used together with any of the following:
This option supports the same placeholders as xref:output-file[outputFile].
For additional details, see xref:language-reference:index.adoc#multiple-file-output[Multiple File Output]
For additional details, see xref:language-reference:index.adoc#multiple-file-output[Multiple File Output]
in the language reference.
====
@@ -303,6 +298,22 @@ Example: `junitReportsDir = layout.buildDirectory.dir("reports")` +
Whether and where to generate JUnit XML reports.
====
[[junit-aggregate-reports]]
.junitAggregateReports: Property<Boolean>
[%collapsible]
====
Default: `false` +
Aggregate JUnit reports into a single file.
====
[[junit-aggregate-suite-name]]
.junitAggregateSuiteName: Property<String>
[%collapsible]
====
Default: `null` +
The name of the root JUnit test suite.
====
[[overwrite]]
.overwrite: Property<Boolean>
[%collapsible]
@@ -366,7 +377,7 @@ $ ./gradlew genJava
----
For a ready-to-go example with full source code,
see link:{uri-codegen-java-example}[codegen-java] in the _pkl/pkl-examples_ repository.
see link:{uri-codegen-java-example}[codegen-java] in the _pkl-jvm-examples_ repository.
=== Configuration Options
@@ -378,14 +389,26 @@ Example: `generateGetters = true` +
Whether to generate private final fields and public getter methods rather than public final fields.
====
// TODO: fixme (paramsAnnotation, nonNullAnnotation)
.preferJavaxInjectAnnotation: Boolean
.paramsAnnotation: Property<String>
[%collapsible]
====
Default: `false` +
Example: `preferJavaxInjectAnnotation = true` +
Whether to annotate constructor parameters with `@javax.inject.Named` instead of `@org.pkl.config.java.mapper.Named`.
If `true`, the generated code will have a compile dependency on `javax.inject:javax.inject:1`.
Default: `null` if `generateSpringBootConfig` is `true`, `"org.pkl.config.java.mapper.Named"` otherwise+
Example: `paramsAnnotation = "org.project.MyAnnotation"` +
Fully qualified name of the annotation type to use for annotating constructor parameters with their name. +
The specified annotation type must have a `value` parameter of type `String` or the generated code may not compile.
If set to `null`, constructor parameters are not annotated.
Whether and how constructor parameters should be annotated depends on the library that instantiates the generated classes.
For Spring Boot applications, and for users of `pkl-config-java` compiling the generated classes with `-parameters`, no annotation is required.
====
.nonNullAnnotation: Property<String>
[%collapsible]
====
Default: `"org.pkl.config.java.mapper.NonNull"` +
Example: `nonNullAnnotation = "org.project.MyAnnotation"` +
Fully qualified name of the annotation type to use for annotating non-null types. +
The specified annotation type must be annotated with `@java.lang.annotation.Target(ElementType.TYPE_USE)`
or the generated code may not compile.
====
Common code generation properties:
@@ -424,7 +447,7 @@ build.gradle.kts::
+
[source,kotlin]
----
pkl {
pkl {
kotlinCodeGenerators {
register("genKotlin") {
sourceModules.addAll(files("Template1.pkl", "Template2.pkl"))
@@ -444,12 +467,19 @@ $ ./gradlew genKotlin
----
For a ready-to-go example with full source code,
see link:{uri-codegen-kotlin-example}[codegen-kotlin] in the _pkl/pkl-examples_ repository.
see link:{uri-codegen-kotlin-example}[codegen-kotlin] in the _pkl-jvm-examples_ repository.
=== Configuration Options
// TODO: fixme (generateKdoc)
(None)
=== Configuration Options
.generateKdoc: Property<Boolean>
[%collapsible]
====
Default: `false` +
Example: `generateKdoc = true` +
Whether to preserve Pkl doc comments by generating corresponding KDoc comments.
====
Common code generation properties:
@@ -506,7 +536,7 @@ $ ./gradlew pkldoc
----
For a ready-to-go example with full source code,
see link:{uri-pkldoc-example}[pkldoc] in the _pkl/pkl-examples_ repository.
see link:{uri-pkldoc-example}[pkldoc] in the _pkl-jvm-examples_ repository.
=== Configuration Options
@@ -520,6 +550,17 @@ Example: `outputDir = layout.projectDirectory.dir("pkl-docs")` +
The directory where generated documentation is placed.
====
.noSymlinks: Property<Boolean>
[%collapsible]
====
Default: `false` +
Example: `noSymlinks = true` +
Create copies of files and directories instead of symbolic links.
In particular, this affects how the "current" directories containing documentation content for the last generated version should be created.
By default, a symbolic link is created pointing to the last generated version.
If symlinks are disabled, a full copy of the last generated version is created.
====
Common properties:
include::../partials/gradle-modules-properties.adoc[]
@@ -691,3 +732,61 @@ The project directories to create packages for.
Common properties:
include::../partials/gradle-common-properties.adoc[]
[[analyze-imports]]
== Analyze Imports
This feature is the Gradle analogy for the xref:pkl-cli:index.adoc#command-analyze-imports[analyze imports] command in the CLI. It builds a graph of imports of the provided source modules.
=== Usage
[tabs]
====
build.gradle::
+
[source,groovy]
----
pkl {
analyzers {
imports {
appConfig {
sourceModules.add(file("src/main/resources/appConfig.pkl"))
}
}
}
}
----
build.gradle.kts::
+
[source,kotlin]
----
pkl {
analyzers {
imports {
register("appConfig") {
sourceModules.add(file("src/main/resources/appConfig.pkl"))
}
}
}
}
----
====
=== Configuration Options
.outputFormat: Property<String>
[%collapsible]
====
Same meaning as <<output-format,outputFormat>> in <<module-evaluation>>.
====
.outputFile: RegularFileProperty<String>
[%collapsible]
====
Same meaning as <<output-file,outputFile>> in <<module-evaluation>>.
====
Common properties:
include::../partials/gradle-modules-properties.adoc[]

View File

@@ -36,6 +36,22 @@ Example: `generateSpringBootConfig = true` +
Whether to generate config classes for use with Spring Boot.
====
.implementSerializable: Property<Boolean>
[%collapsible]
====
Default: `false` +
Example: `implementSerializable = true` +
Whether to generate classes that implement `java.io.Serializable`.
====
.addGeneratedAnnotation: Property<Boolean>
[%collapsible]
====
Default: `false` +
Example: `addGeneratedAnnotation = true` +
Whether to add the `org.pkl.config.java.Generated` annotation to generated types.
====
.renames: MapProperty<String, String>
[%collapsible]
====
@@ -86,4 +102,3 @@ Keys in this mapping can be arbitrary strings, including an empty string.
Values must be valid dot-separated fully qualifed class name prefixes, possibly terminated by a dot.
====
// TODO: fixme (implementSerializable)

View File

@@ -7,7 +7,6 @@ URI patterns that determine which modules can be loaded and evaluated.
Patterns are matched against the beginning of module URIs.
(File paths have been converted to `file:` URLs at this stage.)
At least one pattern needs to match for a module to be loadable.
Both source modules and transitive modules are subject to this check.
====
.allowedResources: ListProperty<String>
@@ -68,6 +67,13 @@ The cache directory for storing packages.
If `null`, defaults to `~/.pkl/cache`.
====
.color: Property<Boolean>
[%collapsible]
====
Default: `false` +
Format messages using ANSI color.
====
.noCache: Property<Boolean>
[%collapsible]
====
@@ -101,3 +107,14 @@ Example: `noProxy = ["example.com", "169.254.0.0/16"]` +
Hosts to which all connections should bypass the proxy.
Hosts can be specified by name, IP address, or IP range using https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation[CIDR notation].
====
.httpRewrites: MapProperty<String, String>
[%collapsible]
====
Default: `null` +
Example: `httpRewrites = [uri("https://pkg.pkl-lang.org/"): uri("https://my.internal.mirror/")]` +
Replace outbound HTTP(S) requests from one URL with another URL.
The left-hand side describes the source prefix, and the right-hand describes the target prefix.
This option is commonly used to enable package mirroring.
The above example will rewrite URL `\https://pkg.pkl-lang.org/pkl-k8s/k8s@1.0.0` to `\https://my.internal.mirror/pkl-k8s/k8s@1.0.0`.
====

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