mirror of
https://github.com/apple/pkl.git
synced 2026-03-14 06:05:42 +01:00
Initial commit
This commit is contained in:
154
.circleci/config.pkl
Normal file
154
.circleci/config.pkl
Normal file
@@ -0,0 +1,154 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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 ".../pkl-project-commons/packages/pkl.impl.circleci/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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local gradleCheckJobs: Mapping<String, GradleCheckJob> = new {
|
||||
["gradle-check-jdk11"] {
|
||||
javaVersion = "11.0"
|
||||
isRelease = false
|
||||
}
|
||||
["gradle-check-jdk17"] {
|
||||
javaVersion = "17.0"
|
||||
isRelease = false
|
||||
}
|
||||
}
|
||||
|
||||
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 = #"""
|
||||
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/*
|
||||
"""#
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
870
.circleci/config.yml
Normal file
870
.circleci/config.yml
Normal file
@@ -0,0 +1,870 @@
|
||||
# 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 -DreleaseBuild=true pkl-cli:macExecutableAmd64 pkl-core:testMacExecutableAmd64
|
||||
name: gradle buildNative
|
||||
- persist_to_workspace:
|
||||
root: '.'
|
||||
paths:
|
||||
- pkl-cli/build/executable/
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: ~/test-results
|
||||
environment:
|
||||
LANG: en_US.UTF-8
|
||||
resource_class: macos.m1.large.gen1
|
||||
macos:
|
||||
xcode: 15.2.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/temurin11-binaries/releases/download/jdk-11.0.20.1%2B1/OpenJDK11U-jdk_x64_linux_hotspot_11.0.20.1_1.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 -DreleaseBuild=true pkl-cli:linuxExecutableAmd64 pkl-core:testLinuxExecutableAmd64
|
||||
name: gradle buildNative
|
||||
- persist_to_workspace:
|
||||
root: '.'
|
||||
paths:
|
||||
- pkl-cli/build/executable/
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- 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: git apply patches/graalVm23.patch
|
||||
- run:
|
||||
command: |-
|
||||
export PATH=~/staticdeps/bin:$PATH
|
||||
./gradlew --info --stacktrace -DreleaseBuild=true pkl-cli:macExecutableAarch64 pkl-core:testMacExecutableAarch64
|
||||
name: gradle buildNative
|
||||
- persist_to_workspace:
|
||||
root: '.'
|
||||
paths:
|
||||
- pkl-cli/build/executable/
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: ~/test-results
|
||||
environment:
|
||||
LANG: en_US.UTF-8
|
||||
resource_class: macos.m1.large.gen1
|
||||
macos:
|
||||
xcode: 15.2.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/temurin11-binaries/releases/download/jdk-11.0.20.1%2B1/OpenJDK11U-jdk_aarch64_linux_hotspot_11.0.20.1_1.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 -DreleaseBuild=true pkl-cli:linuxExecutableAarch64 pkl-core:testLinuxExecutableAarch64
|
||||
name: gradle buildNative
|
||||
- persist_to_workspace:
|
||||
root: '.'
|
||||
paths:
|
||||
- pkl-cli/build/executable/
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- 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/temurin11-binaries/releases/download/jdk-11.0.20.1%2B1/OpenJDK11U-jdk_x64_linux_hotspot_11.0.20.1_1.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 -DreleaseBuild=true pkl-cli:alpineExecutableAmd64 pkl-core:testAlpineExecutableAmd64
|
||||
name: gradle buildNative
|
||||
- persist_to_workspace:
|
||||
root: '.'
|
||||
paths:
|
||||
- pkl-cli/build/executable/
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- 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-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 pkl-cli:macExecutableAmd64 pkl-core:testMacExecutableAmd64
|
||||
name: gradle buildNative
|
||||
- persist_to_workspace:
|
||||
root: '.'
|
||||
paths:
|
||||
- pkl-cli/build/executable/
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: ~/test-results
|
||||
environment:
|
||||
LANG: en_US.UTF-8
|
||||
resource_class: macos.m1.large.gen1
|
||||
macos:
|
||||
xcode: 15.2.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/temurin11-binaries/releases/download/jdk-11.0.20.1%2B1/OpenJDK11U-jdk_x64_linux_hotspot_11.0.20.1_1.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 pkl-cli:linuxExecutableAmd64 pkl-core:testLinuxExecutableAmd64
|
||||
name: gradle buildNative
|
||||
- persist_to_workspace:
|
||||
root: '.'
|
||||
paths:
|
||||
- pkl-cli/build/executable/
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- 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: git apply patches/graalVm23.patch
|
||||
- run:
|
||||
command: |-
|
||||
export PATH=~/staticdeps/bin:$PATH
|
||||
./gradlew --info --stacktrace pkl-cli:macExecutableAarch64 pkl-core:testMacExecutableAarch64
|
||||
name: gradle buildNative
|
||||
- persist_to_workspace:
|
||||
root: '.'
|
||||
paths:
|
||||
- pkl-cli/build/executable/
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: ~/test-results
|
||||
environment:
|
||||
LANG: en_US.UTF-8
|
||||
resource_class: macos.m1.large.gen1
|
||||
macos:
|
||||
xcode: 15.2.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/temurin11-binaries/releases/download/jdk-11.0.20.1%2B1/OpenJDK11U-jdk_aarch64_linux_hotspot_11.0.20.1_1.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 pkl-cli:linuxExecutableAarch64 pkl-core:testLinuxExecutableAarch64
|
||||
name: gradle buildNative
|
||||
- persist_to_workspace:
|
||||
root: '.'
|
||||
paths:
|
||||
- pkl-cli/build/executable/
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- 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/temurin11-binaries/releases/download/jdk-11.0.20.1%2B1/OpenJDK11U-jdk_x64_linux_hotspot_11.0.20.1_1.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 pkl-cli:alpineExecutableAmd64 pkl-core:testAlpineExecutableAmd64
|
||||
name: gradle buildNative
|
||||
- persist_to_workspace:
|
||||
root: '.'
|
||||
paths:
|
||||
- pkl-cli/build/executable/
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: ~/test-results
|
||||
environment:
|
||||
LANG: en_US.UTF-8
|
||||
JAVA_HOME: /jdk
|
||||
resource_class: xlarge
|
||||
docker:
|
||||
- image: oraclelinux:8-slim
|
||||
gradle-check-jdk11:
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
command: ./gradlew --info --stacktrace check
|
||||
name: gradle check
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: ~/test-results
|
||||
environment:
|
||||
LANG: en_US.UTF-8
|
||||
docker:
|
||||
- image: cimg/openjdk:11.0
|
||||
gradle-check-jdk17:
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
command: ./gradlew --info --stacktrace check
|
||||
name: gradle check
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: ~/test-results
|
||||
environment:
|
||||
LANG: en_US.UTF-8
|
||||
docker:
|
||||
- image: cimg/openjdk:17.0
|
||||
bench:
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
command: ./gradlew --info --stacktrace bench:jmh
|
||||
name: bench:jmh
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: ~/test-results
|
||||
environment:
|
||||
LANG: en_US.UTF-8
|
||||
docker:
|
||||
- image: cimg/openjdk:11.0
|
||||
gradle-compatibility:
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
command: |-
|
||||
./gradlew --info --stacktrace :pkl-gradle:build \
|
||||
:pkl-gradle:compatibilityTestReleases \
|
||||
:pkl-gradle:compatibilityTestCandidate
|
||||
name: gradle compatibility
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: ~/test-results
|
||||
environment:
|
||||
LANG: en_US.UTF-8
|
||||
docker:
|
||||
- image: cimg/openjdk:11.0
|
||||
deploy-snapshot:
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: '.'
|
||||
- run:
|
||||
command: ./gradlew --info --stacktrace publishToSonatype
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: ~/test-results
|
||||
environment:
|
||||
LANG: en_US.UTF-8
|
||||
docker:
|
||||
- image: cimg/openjdk:11.0
|
||||
deploy-release:
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: '.'
|
||||
- run:
|
||||
command: ./gradlew --info --stacktrace -DreleaseBuild=true publishToSonatype closeAndReleaseSonatypeStagingRepository
|
||||
- run:
|
||||
command: |-
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \;
|
||||
name: Gather test results
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: ~/test-results
|
||||
environment:
|
||||
LANG: en_US.UTF-8
|
||||
docker:
|
||||
- image: cimg/openjdk:11.0
|
||||
github-release:
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: '.'
|
||||
- run:
|
||||
command: |-
|
||||
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-jdk11:
|
||||
requires:
|
||||
- hold
|
||||
- pr-approval/authenticate
|
||||
- gradle-check-jdk17:
|
||||
requires:
|
||||
- hold
|
||||
- pr-approval/authenticate
|
||||
when:
|
||||
matches:
|
||||
value: << pipeline.git.branch >>
|
||||
pattern: ^pull/\d+(/head)?$
|
||||
main:
|
||||
jobs:
|
||||
- gradle-check-jdk11
|
||||
- gradle-check-jdk17
|
||||
- bench
|
||||
- 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
|
||||
- deploy-snapshot:
|
||||
requires:
|
||||
- gradle-check-jdk11
|
||||
- gradle-check-jdk17
|
||||
- bench
|
||||
- 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
|
||||
context: pkl-maven-release
|
||||
- trigger-docsite-build:
|
||||
requires:
|
||||
- deploy-snapshot
|
||||
context:
|
||||
- pkl-pr-approval
|
||||
when:
|
||||
equal:
|
||||
- main
|
||||
- << pipeline.git.branch >>
|
||||
release:
|
||||
jobs:
|
||||
- gradle-check-jdk11:
|
||||
filters:
|
||||
branches:
|
||||
ignore: /.*/
|
||||
tags:
|
||||
only: /^v?\d+\.\d+\.\d+$/
|
||||
- gradle-check-jdk17:
|
||||
filters:
|
||||
branches:
|
||||
ignore: /.*/
|
||||
tags:
|
||||
only: /^v?\d+\.\d+\.\d+$/
|
||||
- bench:
|
||||
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+$/
|
||||
- github-release:
|
||||
requires:
|
||||
- gradle-check-jdk11
|
||||
- gradle-check-jdk17
|
||||
- bench
|
||||
- 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
|
||||
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+$/
|
||||
167
.circleci/jobs/BuildNativeJob.pkl
Normal file
167
.circleci/jobs/BuildNativeJob.pkl
Normal file
@@ -0,0 +1,167 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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"
|
||||
|
||||
// TODO(oss) replace these with package imports
|
||||
import ".../pkl-pantry/packages/com.circleci.v2/CircleCI.pkl"
|
||||
import ".../pkl-pantry/packages/pkl.experimental.uri/URI.pkl"
|
||||
|
||||
/// The OS to run on
|
||||
os: "macOS"|"linux"
|
||||
|
||||
/// The architecture to use
|
||||
arch: "amd64"|"aarch64"
|
||||
|
||||
/// Whether to link to musl. Otherwise, links to glibc.
|
||||
musl: Boolean = false
|
||||
|
||||
local setupLinuxEnvironment: CircleCI.RunStep =
|
||||
let (jdkVersion = "11.0.20.1+1")
|
||||
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 CircleCI.RestoreCacheStep {
|
||||
name = "Restore static deps from cache"
|
||||
key = "staticdeps-\(arch)"
|
||||
}
|
||||
setupLinuxEnvironment
|
||||
new CircleCI.SaveCacheStep {
|
||||
name = "Save statics deps to cache"
|
||||
key = "staticdeps-\(arch)"
|
||||
paths {
|
||||
"~/staticdeps"
|
||||
}
|
||||
}
|
||||
}
|
||||
when (os == "macOS" && arch == "amd64") {
|
||||
new CircleCI.RunStep {
|
||||
name = "Installing Rosetta 2"
|
||||
command = """
|
||||
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
|
||||
"""
|
||||
}
|
||||
}
|
||||
// If building macOS/aarch64, we need to use GraalVM 23.
|
||||
// We can't use GraalVM 23 for any other build because we need to support Java 11, which was
|
||||
// dropped in GraalVM 23.
|
||||
when (os == "macOS" && arch == "aarch64") {
|
||||
new CircleCI.RunStep {
|
||||
command = "git apply patches/graalVm23.patch"
|
||||
}
|
||||
}
|
||||
new CircleCI.RunStep {
|
||||
name = "gradle buildNative"
|
||||
local _os =
|
||||
if (os == "macOS") "mac"
|
||||
else if (musl) "alpine"
|
||||
else "linux"
|
||||
local jobName = "\(_os)Executable\(arch.capitalize())"
|
||||
command = #"""
|
||||
export PATH=~/staticdeps/bin:$PATH
|
||||
./gradlew \#(module.gradleArgs) pkl-cli:\#(jobName) pkl-core:test\#(jobName.capitalize())
|
||||
"""#
|
||||
}
|
||||
new CircleCI.PersistToWorkspaceStep {
|
||||
root = "."
|
||||
paths {
|
||||
"pkl-cli/build/executable/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
job {
|
||||
when (os == "macOS") {
|
||||
macos {
|
||||
xcode = "15.2.0"
|
||||
}
|
||||
// Use M1 for all architectures. We build amd64/aarch64 based on the GraalVM version,
|
||||
// which gets patched in via `git apply patches/graalVm23.patch`.
|
||||
resource_class = "macos.m1.large.gen1"
|
||||
} else {
|
||||
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"
|
||||
}
|
||||
}
|
||||
35
.circleci/jobs/DeployJob.pkl
Normal file
35
.circleci/jobs/DeployJob.pkl
Normal file
@@ -0,0 +1,35 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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 ".../pkl-pantry/packages/com.circleci.v2/CircleCI.pkl"
|
||||
|
||||
local self = this
|
||||
|
||||
command: String
|
||||
|
||||
job {
|
||||
docker {
|
||||
new { image = "cimg/openjdk:11.0" }
|
||||
}
|
||||
}
|
||||
|
||||
steps {
|
||||
new CircleCI.AttachWorkspaceStep { at = "." }
|
||||
new CircleCI.RunStep {
|
||||
command = "./gradlew \(self.gradleArgs) \(module.command)"
|
||||
}
|
||||
}
|
||||
35
.circleci/jobs/GradleCheckJob.pkl
Normal file
35
.circleci/jobs/GradleCheckJob.pkl
Normal file
@@ -0,0 +1,35 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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 ".../pkl-pantry/packages/com.circleci.v2/CircleCI.pkl"
|
||||
|
||||
javaVersion: "11.0"|"17.0"
|
||||
|
||||
steps {
|
||||
new CircleCI.RunStep {
|
||||
name = "gradle check"
|
||||
command = "./gradlew \(module.gradleArgs) check"
|
||||
}
|
||||
}
|
||||
|
||||
job {
|
||||
docker {
|
||||
new {
|
||||
image = "cimg/openjdk:\(javaVersion)"
|
||||
}
|
||||
}
|
||||
}
|
||||
53
.circleci/jobs/GradleJob.pkl
Normal file
53
.circleci/jobs/GradleJob.pkl
Normal file
@@ -0,0 +1,53 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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 ".../pkl-pantry/packages/com.circleci.v2/CircleCI.pkl"
|
||||
|
||||
/// Whether this is a release build or not.
|
||||
isRelease: Boolean = false
|
||||
|
||||
fixed gradleArgs = new Listing {
|
||||
"--info"
|
||||
"--stacktrace"
|
||||
when (isRelease) {
|
||||
"-DreleaseBuild=true"
|
||||
}
|
||||
}.join(" ")
|
||||
|
||||
steps: Listing<CircleCI.Step>
|
||||
|
||||
job: CircleCI.Job = new {
|
||||
environment {
|
||||
["LANG"] = "en_US.UTF-8"
|
||||
}
|
||||
steps {
|
||||
"checkout"
|
||||
...module.steps
|
||||
new CircleCI.RunStep {
|
||||
// find all test results and write them to the home dir
|
||||
name = "Gather test results"
|
||||
command = """
|
||||
mkdir ~/test-results/
|
||||
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/ \\;
|
||||
"""
|
||||
`when` = "always"
|
||||
}
|
||||
new CircleCI.StoreTestResults {
|
||||
path = "~/test-results"
|
||||
}
|
||||
}
|
||||
}
|
||||
37
.circleci/jobs/SimpleGradleJob.pkl
Normal file
37
.circleci/jobs/SimpleGradleJob.pkl
Normal file
@@ -0,0 +1,37 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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 ".../pkl-pantry/packages/com.circleci.v2/CircleCI.pkl"
|
||||
|
||||
name: String = command
|
||||
|
||||
command: String
|
||||
|
||||
steps {
|
||||
new CircleCI.RunStep {
|
||||
name = module.name
|
||||
command = """
|
||||
./gradlew \(module.gradleArgs) \(module.command)
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
job {
|
||||
docker {
|
||||
new { image = "cimg/openjdk:11.0" }
|
||||
}
|
||||
}
|
||||
10
.editorconfig
Normal file
10
.editorconfig
Normal file
@@ -0,0 +1,10 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
# don't trim whitespace within (say) a Pkl multiline string
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = true
|
||||
max_line_length = 100
|
||||
6
.gitattributes
vendored
Normal file
6
.gitattributes
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# linguist-generated would suppress files in diffs
|
||||
**/src/test/files/** linguist-vendored
|
||||
|
||||
/docs/** linguist-documentation
|
||||
|
||||
*.pkl linguist-language=Groovy
|
||||
8
.githooks/pre-commit
Executable file
8
.githooks/pre-commit
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
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
|
||||
fi
|
||||
19
.gitignore
vendored
Normal file
19
.gitignore
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# macOS
|
||||
.DS_STORE
|
||||
|
||||
# Gradle
|
||||
.gradle/
|
||||
build/
|
||||
generated/
|
||||
|
||||
# IntelliJ
|
||||
.idea/
|
||||
!.idea/codestyles/
|
||||
!.idea/inspectionProfiles/
|
||||
!.idea/runConfigurations/
|
||||
!.idea/scopes/
|
||||
!.idea/vcs.xml
|
||||
|
||||
# :pkl-core:makeIntelliJAntlrPluginHappy
|
||||
gen/
|
||||
PklLexer.tokens
|
||||
600
.idea/codeStyles/Project.xml
generated
Normal file
600
.idea/codeStyles/Project.xml
generated
Normal file
@@ -0,0 +1,600 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<option name="OTHER_INDENT_OPTIONS">
|
||||
<value>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
||||
<value />
|
||||
</option>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="" withSubpackages="true" static="true" />
|
||||
<emptyLine />
|
||||
<package name="" withSubpackages="true" static="false" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RIGHT_MARGIN" value="100" />
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="ALIGN_MULTILINE_FOR" value="false" />
|
||||
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
||||
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||
<option name="THROWS_KEYWORD_WRAP" value="1" />
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1" />
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||
<option name="FOR_STATEMENT_WRAP" value="1" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||
<option name="WRAP_COMMENTS" value="true" />
|
||||
<option name="IF_BRACE_FORCE" value="3" />
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||
<option name="FOR_BRACE_FORCE" value="3" />
|
||||
<AndroidXmlCodeStyleSettings>
|
||||
<option name="USE_CUSTOM_SETTINGS" value="true" />
|
||||
<option name="LAYOUT_SETTINGS">
|
||||
<value>
|
||||
<option name="INSERT_BLANK_LINE_BEFORE_TAG" value="false" />
|
||||
</value>
|
||||
</option>
|
||||
</AndroidXmlCodeStyleSettings>
|
||||
<JSCodeStyleSettings version="0">
|
||||
<option name="INDENT_CHAINED_CALLS" value="false" />
|
||||
</JSCodeStyleSettings>
|
||||
<JavaCodeStyleSettings>
|
||||
<option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
||||
<value />
|
||||
</option>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="" withSubpackages="true" static="true" />
|
||||
<emptyLine />
|
||||
<package name="" withSubpackages="true" static="false" />
|
||||
</value>
|
||||
</option>
|
||||
</JavaCodeStyleSettings>
|
||||
<Objective-C>
|
||||
<option name="INDENT_NAMESPACE_MEMBERS" value="0" />
|
||||
<option name="INDENT_C_STRUCT_MEMBERS" value="2" />
|
||||
<option name="INDENT_CLASS_MEMBERS" value="2" />
|
||||
<option name="INDENT_VISIBILITY_KEYWORDS" value="1" />
|
||||
<option name="INDENT_INSIDE_CODE_BLOCK" value="2" />
|
||||
<option name="KEEP_STRUCTURES_IN_ONE_LINE" value="true" />
|
||||
<option name="FUNCTION_PARAMETERS_WRAP" value="5" />
|
||||
<option name="FUNCTION_CALL_ARGUMENTS_WRAP" value="5" />
|
||||
<option name="TEMPLATE_CALL_ARGUMENTS_WRAP" value="5" />
|
||||
<option name="TEMPLATE_CALL_ARGUMENTS_ALIGN_MULTILINE" value="true" />
|
||||
<option name="ALIGN_INIT_LIST_IN_COLUMNS" value="false" />
|
||||
<option name="SPACE_BEFORE_SUPERCLASS_COLON" value="false" />
|
||||
</Objective-C>
|
||||
<Objective-C-extensions>
|
||||
<option name="GENERATE_INSTANCE_VARIABLES_FOR_PROPERTIES" value="ASK" />
|
||||
<option name="RELEASE_STYLE" value="IVAR" />
|
||||
<option name="TYPE_QUALIFIERS_PLACEMENT" value="BEFORE" />
|
||||
<file>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||
</file>
|
||||
<class>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||
</class>
|
||||
<extensions>
|
||||
<pair source="cc" header="h" />
|
||||
<pair source="c" header="h" />
|
||||
</extensions>
|
||||
</Objective-C-extensions>
|
||||
<Python>
|
||||
<option name="USE_CONTINUATION_INDENT_FOR_ARGUMENTS" value="true" />
|
||||
</Python>
|
||||
<ScalaCodeStyleSettings>
|
||||
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
|
||||
</ScalaCodeStyleSettings>
|
||||
<TypeScriptCodeStyleSettings version="0">
|
||||
<option name="INDENT_CHAINED_CALLS" value="false" />
|
||||
</TypeScriptCodeStyleSettings>
|
||||
<XML>
|
||||
<option name="XML_ALIGN_ATTRIBUTES" value="false" />
|
||||
</XML>
|
||||
<codeStyleSettings language="CSS">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="ECMA Script Level 4">
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="ALIGN_MULTILINE_FOR" value="false" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
||||
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1" />
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||
<option name="FOR_STATEMENT_WRAP" value="1" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||
<option name="IF_BRACE_FORCE" value="3" />
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||
<option name="FOR_BRACE_FORCE" value="3" />
|
||||
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="HTML">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="ALIGN_MULTILINE_RESOURCES" value="false" />
|
||||
<option name="ALIGN_MULTILINE_FOR" value="false" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
||||
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||
<option name="THROWS_KEYWORD_WRAP" value="1" />
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1" />
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||
<option name="FOR_STATEMENT_WRAP" value="1" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||
<option name="WRAP_COMMENTS" value="true" />
|
||||
<option name="IF_BRACE_FORCE" value="3" />
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||
<option name="FOR_BRACE_FORCE" value="3" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JSON">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JavaScript">
|
||||
<option name="RIGHT_MARGIN" value="80" />
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="ALIGN_MULTILINE_FOR" value="false" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_WRAP" value="1" />
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1" />
|
||||
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||
<option name="FOR_STATEMENT_WRAP" value="1" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||
<option name="IF_BRACE_FORCE" value="3" />
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||
<option name="FOR_BRACE_FORCE" value="3" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="ObjectiveC">
|
||||
<option name="RIGHT_MARGIN" value="80" />
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
|
||||
<option name="BLANK_LINES_BEFORE_IMPORTS" value="0" />
|
||||
<option name="BLANK_LINES_AFTER_IMPORTS" value="0" />
|
||||
<option name="BLANK_LINES_AROUND_CLASS" value="0" />
|
||||
<option name="BLANK_LINES_AROUND_METHOD" value="0" />
|
||||
<option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0" />
|
||||
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="false" />
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
|
||||
<option name="FOR_STATEMENT_WRAP" value="1" />
|
||||
<option name="ASSIGNMENT_WRAP" value="1" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="PROTO">
|
||||
<option name="RIGHT_MARGIN" value="80" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="Python">
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="RIGHT_MARGIN" value="80" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="SASS">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="SCSS">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="TypeScript">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:.*Style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_width</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_height</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_weight</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_margin</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginTop</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginBottom</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginStart</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginEnd</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginLeft</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_marginRight</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:padding</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingTop</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingBottom</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingStart</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingEnd</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingLeft</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:paddingRight</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res-auto</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/tools</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="protobuf">
|
||||
<option name="RIGHT_MARGIN" value="80" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
||||
46
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
46
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,46 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="CanBeFinal" enabled="true" level="INFORMATION" enabled_by_default="false">
|
||||
<scope name="AllExceptTruffleAst" level="WARNING" enabled="true">
|
||||
<option name="REPORT_CLASSES" value="false" />
|
||||
<option name="REPORT_METHODS" value="false" />
|
||||
<option name="REPORT_FIELDS" value="true" />
|
||||
</scope>
|
||||
<option name="REPORT_CLASSES" value="false" />
|
||||
<option name="REPORT_METHODS" value="false" />
|
||||
<option name="REPORT_FIELDS" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="ClassCanBeRecord" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="FieldMayBeFinal" enabled="true" level="INFORMATION" enabled_by_default="true">
|
||||
<scope name="AllExceptTruffleAst" level="WARNING" enabled="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="JavadocBlankLines" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="NullableProblems" enabled="true" level="WARNING" enabled_by_default="false">
|
||||
<scope name="AllExceptGenerated" level="WARNING" enabled="true">
|
||||
<option name="REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL" value="true" />
|
||||
<option name="REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL" value="true" />
|
||||
<option name="REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE" value="true" />
|
||||
<option name="REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL" value="true" />
|
||||
<option name="REPORT_NOT_ANNOTATED_GETTER" value="true" />
|
||||
<option name="REPORT_NOT_ANNOTATED_SETTER_PARAMETER" value="true" />
|
||||
<option name="REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS" value="true" />
|
||||
<option name="REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD" value="true" />
|
||||
</scope>
|
||||
<option name="REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL" value="true" />
|
||||
<option name="REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL" value="true" />
|
||||
<option name="REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE" value="true" />
|
||||
<option name="REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL" value="true" />
|
||||
<option name="REPORT_NOT_ANNOTATED_GETTER" value="true" />
|
||||
<option name="REPORT_NOT_ANNOTATED_SETTER_PARAMETER" value="true" />
|
||||
<option name="REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS" value="true" />
|
||||
<option name="REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="SameParameterValue" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||
<option name="processCode" value="true" />
|
||||
<option name="processLiterals" value="true" />
|
||||
<option name="processComments" value="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
3
.idea/scopes/AllExceptTruffleAst.xml
generated
Normal file
3
.idea/scopes/AllExceptTruffleAst.xml
generated
Normal file
@@ -0,0 +1,3 @@
|
||||
<component name="DependencyValidationManager">
|
||||
<scope name="AllExceptTruffleAst" pattern="(src:*..*||test:*..*||lib:*..*)&&!src[pkl.pkl-core.main]:com.apple.pkl.core.ast..*&&!src[pkl.pkl-core.main]:com.apple.pkl.core.stdlib..*Nodes" />
|
||||
</component>
|
||||
3
.idea/scopes/AllProjects.xml
generated
Normal file
3
.idea/scopes/AllProjects.xml
generated
Normal file
@@ -0,0 +1,3 @@
|
||||
<component name="DependencyValidationManager">
|
||||
<scope name="AllProjects" pattern="!file[pkl.pkl-core.test]:files//*&&!file[pkl.pkl-doc.test]:files//*&&!file[pkl.pkl-core.main]:antlr//*&&!file[pkl.pkl-core.main]:truffle//*&&!file[pkl.buildSrc.main]:*/" />
|
||||
</component>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
1
.java-version
Normal file
1
.java-version
Normal file
@@ -0,0 +1 @@
|
||||
17.0
|
||||
78
CODE_OF_CONDUCT.adoc
Normal file
78
CODE_OF_CONDUCT.adoc
Normal file
@@ -0,0 +1,78 @@
|
||||
== Code of Conduct
|
||||
|
||||
=== Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our
|
||||
project and our community a harassment-free experience for everyone,
|
||||
regardless of age, body size, disability, ethnicity, sex
|
||||
characteristics, gender identity and expression, level of experience,
|
||||
education, socio-economic status, nationality, personal appearance,
|
||||
race, religion, or sexual identity and orientation.
|
||||
|
||||
=== Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual
|
||||
attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political
|
||||
attacks
|
||||
* Public or private harassment
|
||||
* Publishing others’ private information, such as a physical or
|
||||
electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
=== Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of
|
||||
acceptable behavior and are expected to take appropriate and fair
|
||||
corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit,
|
||||
or reject comments, commits, code, wiki edits, issues, and other
|
||||
contributions that are not aligned to this Code of Conduct, or to ban
|
||||
temporarily or permanently any contributor for other behaviors that they
|
||||
deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
=== Scope
|
||||
|
||||
This Code of Conduct applies within all project spaces, and it also
|
||||
applies when an individual is representing the project or its community
|
||||
in public spaces. Examples of representing a project or community
|
||||
include using an official project e-mail address, posting via an
|
||||
official social media account, or acting as an appointed representative
|
||||
at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
=== Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may
|
||||
be reported by contacting the open source team at
|
||||
opensource-conduct@group.apple.com. All complaints will be reviewed and
|
||||
investigated and will result in a response that is deemed necessary and
|
||||
appropriate to the circumstances. The project team is obligated to
|
||||
maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted
|
||||
separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in
|
||||
good faith may face temporary or permanent repercussions as determined
|
||||
by other members of the project’s leadership.
|
||||
|
||||
=== Attribution
|
||||
|
||||
This Code of Conduct is adapted from the
|
||||
https://www.contributor-covenant.org[Contributor Covenant], version 1.4,
|
||||
available at
|
||||
https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
58
CONTRIBUTING.adoc
Normal file
58
CONTRIBUTING.adoc
Normal file
@@ -0,0 +1,58 @@
|
||||
:uri-github-discussion: https://github.com/apple/pkl/discussions
|
||||
:uri-github-issue-pkl: https://github.com/apple/pkl/issues/new
|
||||
:uri-seven-rules: https://cbea.ms/git-commit/#seven-rules
|
||||
|
||||
= Pkl Contributor's Guide
|
||||
|
||||
Welcome to the Pkl community, and thank you for contributing!
|
||||
This guide explains how to get involved.
|
||||
|
||||
* <<Licensing>>
|
||||
* <<Issue Tracking>>
|
||||
* <<Pull Requests>>
|
||||
|
||||
== Licensing
|
||||
|
||||
Pkl is released under the Apache 2.0 license.
|
||||
This is why we require that, by submitting a pull request, you acknowledge that you have the right to license your contribution to Apple and the community, and agree that your contribution is licensed under the Apache 2.0 license.
|
||||
|
||||
== Issue Tracking
|
||||
|
||||
To file a bug or feature request, use {uri-github-issue-pkl}[GitHub].
|
||||
Be sure to include the following information:
|
||||
|
||||
* Context
|
||||
** What are/were you trying to achieve?
|
||||
** What's the impact of this bug/feature?
|
||||
|
||||
For bug reports, additionally include the following information:
|
||||
|
||||
* The output of `pkl --version`.
|
||||
* The complete error message.
|
||||
* The simplest possible steps to reproduce.
|
||||
|
||||
== Pull Requests
|
||||
|
||||
When preparing a pull request, follow this checklist:
|
||||
|
||||
* Imitate the conventions of surrounding code.
|
||||
* Format code with `./gradlew spotlessApply` (otherwise the build will fail).
|
||||
* Verify that both the JVM build (`./gradlew build`) and native build (`./gradlew buildNative`) succeed.
|
||||
* Follow the {uri-seven-rules}[seven rules] of great Git commit messages:
|
||||
** Separate subject from body with a blank line.
|
||||
** Limit the subject line to 50 characters.footnote:not-enforced[This rule is not enforced in the Pkl project.]
|
||||
** Capitalize the subject line.
|
||||
** Do not end the subject line with a period.
|
||||
** Use the imperative mood in the subject line.
|
||||
** Wrap the body at 72 characters.footnote:not-enforced[]
|
||||
** Use the body to explain what and why vs. how.
|
||||
|
||||
IMPORTANT: If you plan to make substantial changes or add new features,
|
||||
we encourage you to first discuss them with the wider Pkl developer community.
|
||||
You can do this by filing a {uri-github-issue-pkl}[GitHub Issue] or by starting
|
||||
{uri-github-discussion}[GitHub Discussion].
|
||||
This will save time and increases the chance of your pull request being accepted.
|
||||
|
||||
== Maintainers
|
||||
|
||||
The project’s maintainers (those with write access to the upstream repository) are listed in link:MAINTAINERS.adoc[].
|
||||
101
DEVELOPMENT.adoc
Normal file
101
DEVELOPMENT.adoc
Normal file
@@ -0,0 +1,101 @@
|
||||
= Development
|
||||
: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
|
||||
|
||||
== Setup
|
||||
|
||||
. (mandatory) Install {uri-jdk}[OpenJDK 11 HotSpot] (as long as we support JDK11)
|
||||
. (mandatory) Setup Gradle on your system
|
||||
. (recommended) Install {uri-intellij}[IntelliJ IDEA 2023.x] +
|
||||
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) Install {uri-jenv}[jenv] and plugins +
|
||||
_jenv_ use specific JDK versions in certain subdirectories. _Pkl_ comes with a `.java-version` file specifying JDK 17. +
|
||||
Enable _jenv_ plugins for better handling by `gradle`:
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
jenv enable-plugin gradle
|
||||
jenv enable-plugin export
|
||||
----
|
||||
|
||||
== Common Build Commands
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
gw clean
|
||||
gw test
|
||||
gw build # build everything except native executables
|
||||
gw buildNative # build macOS executable on macOS,
|
||||
# Linux and Alpine executables on Linux
|
||||
gw pkldoc # generate standard library docs
|
||||
|
||||
pkl-cli/build/executable/jpkl # run Java executable
|
||||
pkl-cli/build/executable/pkl-macos-amd64 # run Mac executable
|
||||
----
|
||||
|
||||
== Update Gradle
|
||||
|
||||
. Go to https://gradle.org/release-checksums/ and copy the checksum for the new Gradle version
|
||||
. Run the following command *twice* (until it prints UP-TO-DATE):
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
gw wrapper --gradle-version [version] --gradle-distribution-sha256-sum [sha]
|
||||
----
|
||||
. Commit the updated wrapper files
|
||||
|
||||
== Update Dependencies
|
||||
|
||||
. (optional) Update _gradle/libs.version.toml_
|
||||
based on version information from https://search.maven.org, https://plugins.gradle.org, and GitHub repos
|
||||
. Run `gw updateDependencyLocks`
|
||||
. Validate changes with `gw build buildNative`
|
||||
. Review and commit the updated dependency lock files
|
||||
|
||||
== Code Generation
|
||||
|
||||
* 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/`
|
||||
|
||||
== Resources
|
||||
|
||||
=== ANTLR
|
||||
|
||||
* https://github.com/antlr/antlr4/blob/main/doc/index.md[Documentation]
|
||||
* https://groups.google.com/forum/#!forum/antlr-discussion[Forums]
|
||||
* https://github.com/mobileink/lab.clj.antlr/tree/main/doc[Some third-party docs]
|
||||
|
||||
=== Truffle
|
||||
|
||||
* http://ssw.jku.at/Research/Projects/JVM/Truffle.html[Homepage]
|
||||
* https://github.com/graalvm/truffle[GitHub]
|
||||
* http://lafo.ssw.uni-linz.ac.at/javadoc/truffle/latest/[Javadoc]
|
||||
* http://mail.openjdk.java.net/pipermail/graal-dev/[Mailing List]
|
||||
* https://medium.com/@octskyward/graal-truffle-134d8f28fb69#.2db370y2g[Graal & Truffle (Article)]
|
||||
* https://comserv.cs.ut.ee/home/files/Pool_ComputerScience_2016.pdf?study=ATILoputoo&reference=6319668E7151D556131810BC3F4A627D7FEF5F3B[Truffle Overview (see chapter 1)]
|
||||
* https://gist.github.com/smarr/d1f8f2101b5cc8e14e12[Truffle: Languages and Material]
|
||||
* https://github.com/smarr/truffle-notes[Truffle Notes]
|
||||
* https://wiki.openjdk.java.net/display/Graal/Truffle+FAQ+and+Guidelines[Truffle FAQ]
|
||||
|
||||
=== Other Config Languages
|
||||
|
||||
* https://github.com/google/jsonnet[Jsonnet]
|
||||
* https://github.com/dhall-lang/dhall-lang[Dhall]
|
||||
* https://cuelang.org[CUE]
|
||||
* https://nickel-lang.org[Nickel]
|
||||
* https://kcl-lang.io[KCL]
|
||||
* https://github.com/google/skylark[Skylark]
|
||||
* https://github.com/typesafehub/config[Typesafe Config]
|
||||
* https://www.flabbergast.org[Flabbergast]
|
||||
(defunct, http://artefacts.masella.name/2015-srecon-andre_masella.pdf[paper])
|
||||
* https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55[Nix by example: The Nix expression language]
|
||||
* http://lethalman.blogspot.co.at/2014/07/nix-pill-4-basics-of-language.html[Nix pill 4: the basics of the language]
|
||||
* https://docs.puppetlabs.com/puppet/latest/reference/lang_summary.html[Puppet Configuration Language]
|
||||
202
LICENSE.txt
Normal file
202
LICENSE.txt
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
11
MAINTAINERS.adoc
Normal file
11
MAINTAINERS.adoc
Normal file
@@ -0,0 +1,11 @@
|
||||
= MAINTAINERS
|
||||
|
||||
This page lists all active Maintainers of this repository.
|
||||
|
||||
See link:CONTRIBUTING.adoc[] for general contribution guidelines.
|
||||
|
||||
== Maintainers (in alphabetical order)
|
||||
|
||||
* https://github.com/bioball[Daniel Chao]
|
||||
* https://github.com/stackoverflow[Islon Scherer]
|
||||
* https://github.com/holzensp[Philip Hölzenspies]
|
||||
106
NOTICE.txt
Normal file
106
NOTICE.txt
Normal file
@@ -0,0 +1,106 @@
|
||||
Copyright © 2024 Apple Inc. and the Pkl project authors
|
||||
|
||||
|
||||
Portions of this software were originally based on 'SnakeYAML' developed by Andrey Somov.
|
||||
(https://bitbucket.org/asomov/snakeyaml-engine/)
|
||||
|
||||
The Apache License
|
||||
Copyright © 2008-2010 Andrey Somov
|
||||
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.
|
||||
|
||||
Portions of this software were originally based on 'jline3' developed by the JLine authors.
|
||||
(https://github.com/jline/jline3)
|
||||
|
||||
Copyright (c) 2002-2023, the original author(s)
|
||||
|
||||
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 JLine 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.
|
||||
|
||||
Portions of this software were originally based on 'minimal-json' developed by EclipseSource.
|
||||
(https://github.com/ralfstx/minimal-json)
|
||||
|
||||
Copyright (c) 2015, 2016 EclipseSource.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Portions of this software were originally based on 'gson' developed by the Google Inc.
|
||||
(https://github.com/google/gson)
|
||||
|
||||
The Apache License
|
||||
Copyright © 2008 Google 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.
|
||||
|
||||
Portions of this software were originally based on 'guava' developed by Google Inc.
|
||||
(https://github.com/google/guava)
|
||||
|
||||
The Apache License
|
||||
Copyright © 2009 The Guava Authors
|
||||
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.
|
||||
|
||||
Portions of this software were originally based on 'java-string-similarity' developed by Thibault Debatty.
|
||||
(https://github.com/tdebatty/java-string-similarity)
|
||||
|
||||
Copyright 2015 Thibault Debatty
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Portions of this software were originally based on 'xerxes2-j' developed by the Apache Software Foundation.
|
||||
(https://github.com/apache/xerces2-j)
|
||||
|
||||
The Apache License
|
||||
Copyright © 1999-2018 The Apache Software Foundation
|
||||
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.
|
||||
|
||||
Portions of this software were originally based on 'scroll-into-view-if-needed' developed by Cody Olsen.
|
||||
(https://github.com/scroll-into-view/scroll-into-view-if-needed)
|
||||
|
||||
|
||||
Copyright (c) 2023 Cody Olsen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
This product ships with third party licenses that may be distributed under a different license.
|
||||
This information is detailed in THIRD-PARTY-NOTICES.txt.
|
||||
|
||||
Portions of this software includes code from "Gradle" by Gradle, Inc.
|
||||
|
||||
Copyright 2015 the original author or authors.
|
||||
|
||||
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.
|
||||
36
README.adoc
Normal file
36
README.adoc
Normal file
@@ -0,0 +1,36 @@
|
||||
= Pkl
|
||||
|
||||
:uri-homepage: https://pkl-lang.org
|
||||
:uri-docs: {uri-homepage}/main/current
|
||||
:uri-docs-introduction: {uri-docs}/introduction
|
||||
:uri-docs-release-notes: {uri-docs}/release-notes
|
||||
:uri-docs-language: {uri-docs}/language
|
||||
:uri-docs-tools: {uri-docs}/tools
|
||||
:uri-github-issue: https://github.com/apple/pkl/issues
|
||||
:uri-github-discussions: https://github.com/apple/pkl/discussions
|
||||
:uri-pkl-examples: https://pkl-lang.org/main/current/examples.html
|
||||
: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
|
||||
|
||||
A configuration as code language with rich validation and tooling.
|
||||
|
||||
== Quick Links
|
||||
|
||||
* {uri-installation}[Installation]
|
||||
* {uri-lang-reference}[Language Reference]
|
||||
|
||||
== Documentation
|
||||
|
||||
* {uri-homepage}[Home Page]
|
||||
** {uri-docs-introduction}[Introduction]
|
||||
** {uri-docs-language}[Language]
|
||||
** {uri-docs-tools}[Tools]
|
||||
** {uri-pkl-examples}[Examples]
|
||||
** {uri-docs-release-notes}[Release Notes]
|
||||
|
||||
== Community
|
||||
|
||||
We'd love to hear from you!
|
||||
|
||||
* Create an {uri-github-issue}[issue]
|
||||
* Ask a question on {uri-github-discussions}[GitHub Discussions]
|
||||
13
SECURITY.adoc
Normal file
13
SECURITY.adoc
Normal file
@@ -0,0 +1,13 @@
|
||||
= Security
|
||||
|
||||
For the protection of our community, the Pkl team does not disclose, discuss, or confirm security issues until our investigation is complete and any necessary updates are generally available.
|
||||
|
||||
== Reporting a security vulnerability
|
||||
|
||||
If you have discovered a security vulnerability within the Pkl project, please report it to us.
|
||||
We welcome reports from everyone, including security researchers, developers, and users.
|
||||
|
||||
Security vulnerabilities may be reported on the link:https://security.apple.com/submit[Report a vulnerability] form.
|
||||
When submitting a vulnerability, select "Apple Devices and Software" as the affected platform, and "Open Source" as the affected area.
|
||||
|
||||
For more information, see https://pkl-lang.org/security.html.
|
||||
376
THIRD-PARTY-NOTICES.txt
Normal file
376
THIRD-PARTY-NOTICES.txt
Normal file
@@ -0,0 +1,376 @@
|
||||
Pkl ships with third-party libraries that may be distributed under a different license than
|
||||
Pkl's own license.
|
||||
These libraries and their licenses are listed below:
|
||||
|
||||
1) Clikt (https://github.com/ajalt/clikt)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
Copyright © 2018 AJ Alt
|
||||
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.
|
||||
|
||||
2) JavaPoet (http://github.com/square/javapoet/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
Copyright © 2015 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.
|
||||
|
||||
3) KotlinPoet (https://github.com/square/kotlinpoet)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
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)
|
||||
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
|
||||
|
||||
The Apache License
|
||||
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
|
||||
POM License: The 2-Clause BSD License - https://opensource.org/licenses/BSD-2-Clause
|
||||
|
||||
Embedded license:
|
||||
|
||||
****************************************
|
||||
|
||||
Copyright (c) 2015, Atlassian Pty Ltd
|
||||
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.
|
||||
|
||||
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 HOLDER 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.
|
||||
|
||||
7) commonmark-java extension for tables
|
||||
POM License: The 2-Clause BSD License - https://opensource.org/licenses/BSD-2-Clause
|
||||
|
||||
Embedded license:
|
||||
|
||||
****************************************
|
||||
|
||||
Copyright (c) 2015, Atlassian Pty Ltd
|
||||
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.
|
||||
|
||||
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 HOLDER 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.
|
||||
|
||||
8) 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
|
||||
|
||||
The Apache License
|
||||
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)
|
||||
POM License: Universal Permissive License, Version 1.0 - http://opensource.org/licenses/UPL
|
||||
|
||||
10) 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)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
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/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
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/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
Copyright © 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributor
|
||||
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/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
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/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
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/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
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)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
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)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
2017-2019 JetBrains s.r.o and respective authors and developers
|
||||
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)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
2017-2019 JetBrains s.r.o and respective authors and developers
|
||||
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
|
||||
Manifest license URL: https://opensource.org/licenses/BSD-3-Clause
|
||||
|
||||
POM License: The 3-Clause BSD License - https://opensource.org/licenses/BSD-3-Clause
|
||||
|
||||
Copyright (c) 2002-2023, the original author(s)
|
||||
|
||||
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 JLine 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.
|
||||
|
||||
21) 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
|
||||
|
||||
Copyright (c) 2002-2023, the original author(s)
|
||||
|
||||
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 JLine 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.
|
||||
|
||||
22) 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
|
||||
|
||||
Copyright (c) 2002-2023, the original author(s)
|
||||
|
||||
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 JLine 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.
|
||||
|
||||
23) msgpack-core (https://msgpack.org/)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
Copyright © 2016 Sadayuki Furuhashi, Muga Nishizawa, Taro L. Saito, Mitsunori Komatsu, Ozawa Tsuyoshi
|
||||
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)
|
||||
POM License: Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
The Apache License
|
||||
Copyright © 2021 Glen K. Peterson
|
||||
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.
|
||||
|
||||
POM License: Eclipse Public License - v 1.0 - http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
NOTE: The files in this project that came from Clojure (Persistent...) MUST only be used under the Eclipse 1.0 license.
|
||||
At the user's choice, any other files in this project can be used under Eclipse 1.0 or the Apache 2.0 license.
|
||||
|
||||
Eclipse Public License - v 1.0
|
||||
|
||||
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT").
|
||||
ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
|
||||
|
||||
1. DEFINITIONS
|
||||
|
||||
"Contribution" means:
|
||||
|
||||
a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
|
||||
|
||||
b) in the case of each subsequent Contributor:
|
||||
|
||||
i) changes to the Program, and
|
||||
|
||||
ii) additions to the Program;
|
||||
|
||||
where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
|
||||
|
||||
"Contributor" means any person or entity that distributes the Program.
|
||||
|
||||
"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
|
||||
|
||||
"Program" means the Contributions distributed in accordance with this Agreement.
|
||||
|
||||
"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
|
||||
|
||||
2. GRANT OF RIGHTS
|
||||
|
||||
a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
|
||||
|
||||
b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
|
||||
|
||||
c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
|
||||
|
||||
d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
|
||||
|
||||
3. REQUIREMENTS
|
||||
|
||||
A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
|
||||
|
||||
a) it complies with the terms and conditions of this Agreement; and
|
||||
|
||||
b) its license agreement:
|
||||
|
||||
i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
|
||||
|
||||
ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
|
||||
|
||||
iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
|
||||
|
||||
iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
|
||||
|
||||
When the Program is made available in source code form:
|
||||
|
||||
a) it must be made available under this Agreement; and
|
||||
|
||||
b) a copy of this Agreement must be included with each copy of the Program.
|
||||
|
||||
Contributors may not remove or alter any copyright notices contained within the Program.
|
||||
|
||||
Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
|
||||
|
||||
4. COMMERCIAL DISTRIBUTION
|
||||
|
||||
Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
|
||||
|
||||
For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
|
||||
|
||||
5. NO WARRANTY
|
||||
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
6. DISCLAIMER OF LIABILITY
|
||||
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. GENERAL
|
||||
|
||||
If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
|
||||
|
||||
If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
|
||||
|
||||
All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
|
||||
|
||||
Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
The Apache License
|
||||
Copyright © 2008-2010 Andrey Somov
|
||||
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.
|
||||
|
||||
48
bench/bench.gradle.kts
Normal file
48
bench/bench.gradle.kts
Normal file
@@ -0,0 +1,48 @@
|
||||
plugins {
|
||||
pklAllProjects
|
||||
pklJavaLibrary
|
||||
pklGraalVm
|
||||
id("me.champeau.jmh")
|
||||
}
|
||||
|
||||
val truffle: Configuration by configurations.creating
|
||||
val graal: Configuration by configurations.creating
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
dependencies {
|
||||
jmh(project(":pkl-core"))
|
||||
// necessary because antlr4-runtime is declared as implementation dependency in pkl-core.gradle
|
||||
jmh(libs.antlrRuntime)
|
||||
truffle(libs.truffleApi)
|
||||
graal(libs.graalCompiler)
|
||||
}
|
||||
|
||||
jmh {
|
||||
//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.graalVm.baseDir}/bin/java")
|
||||
// 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
|
||||
"-Dgraalvm.locatorDisabled=true --module-path=${truffle.asPath} --upgrade-module-path=${graal.asPath}"
|
||||
)
|
||||
)
|
||||
includeTests.set(false)
|
||||
//threads = Runtime.runtime.availableProcessors() / 2 + 1
|
||||
//synchronizeIterations = false
|
||||
}
|
||||
|
||||
tasks.named("jmh") {
|
||||
dependsOn(":installGraalVm")
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
43
bench/gradle.lockfile
Normal file
43
bench/gradle.lockfile
Normal file
@@ -0,0 +1,43 @@
|
||||
# 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.12.21=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
net.sf.jopt-simple:jopt-simple:5.0.4=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
org.apache.commons:commons-math3:3.2=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
|
||||
org.assertj:assertj-core:3.24.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.compiler:compiler:22.3.1=graal
|
||||
org.graalvm.sdk:graal-sdk:22.3.1=graal,jmh,jmhRuntimeClasspath,truffle
|
||||
org.graalvm.truffle:truffle-api:22.3.1=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.9.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.jupiter:junit-jupiter-engine:5.9.3=testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.jupiter:junit-jupiter-params:5.9.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.9.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.platform:junit-platform-engine:1.9.3=testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit:junit-bom:5.9.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.openjdk.jmh:jmh-core:1.36=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
org.openjdk.jmh:jmh-generator-asm:1.36=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
org.openjdk.jmh:jmh-generator-bytecode:1.36=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
org.openjdk.jmh:jmh-generator-reflection:1.36=jmh,jmhCompileClasspath,jmhImplementationDependenciesMetadata,jmhRuntimeClasspath
|
||||
org.opentest4j:opentest4j:1.2.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
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
|
||||
104
bench/src/jmh/java/org/pkl/core/Fibonacci.java
Normal file
104
bench/src/jmh/java/org/pkl/core/Fibonacci.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.pkl.core;
|
||||
|
||||
import static org.pkl.core.ModuleSource.modulePath;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Warmup(iterations = 5, time = 2)
|
||||
@Measurement(iterations = 5, time = 2)
|
||||
@OutputTimeUnit(TimeUnit.SECONDS)
|
||||
@Fork(1)
|
||||
public class Fibonacci {
|
||||
@Benchmark
|
||||
public long fib_class_java() {
|
||||
return new FibJavaImpl().fib(35);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public long fib_class() {
|
||||
try (var evaluator = Evaluator.preconfigured()) {
|
||||
var module = evaluator.evaluate(modulePath("org/pkl/core/fib_class.pkl"));
|
||||
return (long) module.getProperties().get("result");
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public long fib_class_explicitThis() {
|
||||
try (var evaluator = Evaluator.preconfigured()) {
|
||||
var module = evaluator.evaluate(modulePath("org/pkl/core/fib_class_explicitThis.pkl"));
|
||||
return (long) module.getProperties().get("result");
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public long fib_class_typed() {
|
||||
try (var evaluator = Evaluator.preconfigured()) {
|
||||
var module = evaluator.evaluate(modulePath("org/pkl/core/fib_class_typed.pkl"));
|
||||
return (long) module.getProperties().get("result");
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public long fib_class_constrained1() {
|
||||
try (var evaluator = Evaluator.preconfigured()) {
|
||||
var module = evaluator.evaluate(modulePath("org/pkl/core/fib_class_constrained1.pkl"));
|
||||
return (long) module.getProperties().get("result");
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public long fib_class_constrained2() {
|
||||
try (var evaluator = Evaluator.preconfigured()) {
|
||||
var module = evaluator.evaluate(modulePath("org/pkl/core/fib_class_constrained2.pkl"));
|
||||
return (long) module.getProperties().get("result");
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public long fib_module() {
|
||||
try (var evaluator = Evaluator.preconfigured()) {
|
||||
var module = evaluator.evaluate(modulePath("org/pkl/core/fib_module.pkl"));
|
||||
return (long) module.getProperties().get("result");
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public long fib_module_explicitThis() {
|
||||
try (var evaluator = Evaluator.preconfigured()) {
|
||||
var module = evaluator.evaluate(modulePath("org/pkl/core/fib_module_explicitThis.pkl"));
|
||||
return (long) module.getProperties().get("result");
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public long fib_lambda() {
|
||||
try (var evaluator = Evaluator.preconfigured()) {
|
||||
var module = evaluator.evaluate(modulePath("org/pkl/core/fib_lambda.pkl"));
|
||||
return (long) module.getProperties().get("result");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// kept similar to pkl code (class, instance method, long argument)
|
||||
class FibJavaImpl {
|
||||
long fib(long n) {
|
||||
return n < 2 ? n : fib(n - 1) + fib(n - 2);
|
||||
}
|
||||
}
|
||||
143
bench/src/jmh/java/org/pkl/core/ListSort.java
Normal file
143
bench/src/jmh/java/org/pkl/core/ListSort.java
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.pkl.core;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.*;
|
||||
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.module.ModuleKeyFactories;
|
||||
import org.pkl.core.repl.ReplRequest;
|
||||
import org.pkl.core.repl.ReplResponse;
|
||||
import org.pkl.core.repl.ReplServer;
|
||||
import org.pkl.core.resource.ResourceReaders;
|
||||
import org.pkl.core.util.IoUtils;
|
||||
|
||||
@Warmup(iterations = 5, time = 2)
|
||||
@Measurement(iterations = 5, time = 2)
|
||||
@OutputTimeUnit(TimeUnit.SECONDS)
|
||||
@Fork(1)
|
||||
@SuppressWarnings("unused")
|
||||
public class ListSort {
|
||||
private static final ReplServer repl =
|
||||
new ReplServer(
|
||||
SecurityManagers.defaultManager,
|
||||
Loggers.stdErr(),
|
||||
List.of(ModuleKeyFactories.standardLibrary),
|
||||
List.of(ResourceReaders.file()),
|
||||
Map.of(),
|
||||
Map.of(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
IoUtils.getCurrentWorkingDir(),
|
||||
StackFrameTransformers.defaultTransformer);
|
||||
private static final List<Object> list = new ArrayList<>(100000);
|
||||
|
||||
static {
|
||||
var random = new Random(2786433088656064171L);
|
||||
for (var i = 0; i < 100000; i++) {
|
||||
list.add(random.nextLong());
|
||||
}
|
||||
|
||||
TempFile tempFile;
|
||||
try {
|
||||
tempFile = new TempFileManager().create("bench-nums.txt");
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
try (var fw = new FileWriter(tempFile.getAbsolutePath())) {
|
||||
for (var elem : list) {
|
||||
fw.append(elem.toString()).append('\n');
|
||||
}
|
||||
fw.flush();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
|
||||
var responses =
|
||||
repl.handleRequest(
|
||||
new ReplRequest.Eval(
|
||||
"setup",
|
||||
"import \"pkl:test\"\n"
|
||||
+ "random = test.random\n"
|
||||
+ "nums = read(\"file://"
|
||||
+ tempFile.getAbsolutePath()
|
||||
+ "\").text.split(\"\\n\").dropLast(1).map((it) -> it.toInt())\n"
|
||||
+ "cmp = (x, y) -> if (x < y) -1 else if (x == y) 0 else 1",
|
||||
false,
|
||||
false));
|
||||
if (!responses.isEmpty()) {
|
||||
throw new AssertionError(responses.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public String sortPkl() {
|
||||
var response =
|
||||
repl.handleRequest(
|
||||
// append `.length` to avoid rendering the list
|
||||
new ReplRequest.Eval("sort", "nums.sort().length", false, false))
|
||||
.get(0);
|
||||
if (!(response instanceof ReplResponse.EvalSuccess)) {
|
||||
throw new AssertionError(response);
|
||||
}
|
||||
return ((ReplResponse.EvalSuccess) response).getResult();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public String sortWithPkl() {
|
||||
var response =
|
||||
repl.handleRequest(
|
||||
// append `.length` to avoid rendering the list
|
||||
new ReplRequest.Eval("sort", "nums.sortWith(cmp).length", false, false))
|
||||
.get(0);
|
||||
if (!(response instanceof ReplResponse.EvalSuccess)) {
|
||||
throw new AssertionError(response);
|
||||
}
|
||||
return ((ReplResponse.EvalSuccess) response).getResult();
|
||||
}
|
||||
|
||||
// note that this is an uneven comparison
|
||||
// (timsort vs. merge sort, java.util.ArrayList vs. persistent vector
|
||||
@Benchmark
|
||||
public List<Object> sortJava() {
|
||||
return sort(list);
|
||||
}
|
||||
|
||||
private List<Object> sort(List<Object> self) {
|
||||
var array = self.toArray();
|
||||
Arrays.sort(array);
|
||||
return Arrays.asList(array);
|
||||
}
|
||||
|
||||
// note that this is an uneven comparison
|
||||
// (timsort vs. merge sort, java.util.ArrayList vs. persistent vector
|
||||
@Benchmark
|
||||
public List<Object> sortWithJava() {
|
||||
return sortWith(list, Comparator.comparingLong(x -> (long) x));
|
||||
}
|
||||
|
||||
private List<Object> sortWith(List<Object> self, Comparator<Object> comparator) {
|
||||
var array = self.toArray();
|
||||
Arrays.sort(array, comparator);
|
||||
return Arrays.asList(array);
|
||||
}
|
||||
}
|
||||
59
bench/src/jmh/java/org/pkl/core/parser/ParserBenchmark.java
Normal file
59
bench/src/jmh/java/org/pkl/core/parser/ParserBenchmark.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.pkl.core.parser;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Warmup(iterations = 5, time = 2)
|
||||
@Measurement(iterations = 5, time = 2)
|
||||
@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 {\n"
|
||||
+ " a2 {\n"
|
||||
+ " a3 {\n"
|
||||
+ " a4 {\n"
|
||||
+ " a5 {\n"
|
||||
+ " a6 {\n"
|
||||
+ " a7 {\n"
|
||||
+ " a8 {\n"
|
||||
+ " a9 {\n"
|
||||
+ " a10 {\n"
|
||||
+ " a11 {\n"
|
||||
+ " a12 {\n"
|
||||
+ " a13 = map(map(map((x) -> 1)))\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ "}");
|
||||
}
|
||||
}
|
||||
20
bench/src/jmh/resources/org/pkl/core/fib_class.pkl
Normal file
20
bench/src/jmh/resources/org/pkl/core/fib_class.pkl
Normal file
@@ -0,0 +1,20 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class Fibonacci {
|
||||
function fib(n) = if (n < 2) n else fib(n - 1) + fib(n - 2)
|
||||
}
|
||||
result = new Fibonacci {}.fib(35)
|
||||
@@ -0,0 +1,20 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class Fibonacci {
|
||||
function fib(n: Int(this >= 0)): Int(this >= 0) = if (n < 2) n else fib(n - 1) + fib(n - 2)
|
||||
}
|
||||
result = new Fibonacci {}.fib(35)
|
||||
@@ -0,0 +1,20 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class Fibonacci {
|
||||
function fib(n: Int(isPositive)): Int(isPositive) = if (n < 2) n else fib(n - 1) + fib(n - 2)
|
||||
}
|
||||
result = new Fibonacci {}.fib(35)
|
||||
@@ -0,0 +1,20 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class Fibonacci {
|
||||
function fib(n) = if (n < 2) n else this.fib(n - 1) + this.fib(n - 2)
|
||||
}
|
||||
result = new Fibonacci {}.fib(35)
|
||||
20
bench/src/jmh/resources/org/pkl/core/fib_class_typed.pkl
Normal file
20
bench/src/jmh/resources/org/pkl/core/fib_class_typed.pkl
Normal file
@@ -0,0 +1,20 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class Fibonacci {
|
||||
function fib(n: Int): Int = if (n < 2) n else fib(n - 1) + fib(n - 2)
|
||||
}
|
||||
result = new Fibonacci {}.fib(35)
|
||||
19
bench/src/jmh/resources/org/pkl/core/fib_lambda.pkl
Normal file
19
bench/src/jmh/resources/org/pkl/core/fib_lambda.pkl
Normal file
@@ -0,0 +1,19 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
hidden fib = (n) -> if (n < 2) n else fib.apply(n - 1) + fib.apply(n - 2)
|
||||
|
||||
result = fib.apply(35)
|
||||
18
bench/src/jmh/resources/org/pkl/core/fib_module.pkl
Normal file
18
bench/src/jmh/resources/org/pkl/core/fib_module.pkl
Normal file
@@ -0,0 +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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
function fib(n) = if (n < 2) n else fib(n - 1) + fib(n - 2)
|
||||
result = fib(35)
|
||||
@@ -0,0 +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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
function fib(n) = if (n < 2) n else this.fib(n - 1) + this.fib(n - 2)
|
||||
result = fib(35)
|
||||
67
build.gradle.kts
Normal file
67
build.gradle.kts
Normal file
@@ -0,0 +1,67 @@
|
||||
// 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
|
||||
pklGraalVm
|
||||
|
||||
alias(libs.plugins.ideaExt)
|
||||
alias(libs.plugins.jmh) apply false
|
||||
alias(libs.plugins.nexusPublish)
|
||||
}
|
||||
|
||||
nexusPublishing {
|
||||
repositories {
|
||||
sonatype {
|
||||
nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/"))
|
||||
snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
idea {
|
||||
project {
|
||||
this as ExtensionAware
|
||||
configure<ProjectSettings> {
|
||||
this as ExtensionAware
|
||||
configure<ActionDelegationConfig> {
|
||||
delegateBuildRunToGradle = true
|
||||
testRunner = PLATFORM
|
||||
}
|
||||
configure<TaskTriggersConfig> {
|
||||
afterSync(provider { project(":pkl-core").tasks.named("makeIntelliJAntlrPluginHappy") })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val clean by tasks.registering(Delete::class) {
|
||||
delete(buildDir)
|
||||
}
|
||||
|
||||
val printVersion by tasks.registering {
|
||||
doFirst { println(buildInfo.pklVersion) }
|
||||
}
|
||||
|
||||
val message = """
|
||||
====
|
||||
Gradle version : ${gradle.gradleVersion}
|
||||
Java version : ${System.getProperty("java.version")}
|
||||
isParallel : ${gradle.startParameter.isParallelProjectExecutionEnabled}
|
||||
maxWorkerCount : ${gradle.startParameter.maxWorkerCount}
|
||||
Architecture : ${buildInfo.arch}
|
||||
|
||||
Project Version : ${project.version}
|
||||
Pkl Version : ${buildInfo.pklVersion}
|
||||
Pkl Non-Unique Version : ${buildInfo.pklVersionNonUnique}
|
||||
Git Commit ID : ${buildInfo.commitId}
|
||||
====
|
||||
"""
|
||||
|
||||
val formattedMessage = message.replace("\n====", "\n" + "=".repeat(message.lines().maxByOrNull { it.length }!!.length))
|
||||
logger.info(formattedMessage)
|
||||
17
buildSrc/build.gradle.kts
Normal file
17
buildSrc/build.gradle.kts
Normal file
@@ -0,0 +1,17 @@
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.downloadTaskPlugin)
|
||||
implementation(libs.spotlessPlugin)
|
||||
implementation(libs.kotlinPlugin) {
|
||||
exclude(module = "kotlin-android-extensions")
|
||||
}
|
||||
implementation(libs.shadowPlugin)
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
24
buildSrc/settings.gradle.kts
Normal file
24
buildSrc/settings.gradle.kts
Normal file
@@ -0,0 +1,24 @@
|
||||
@file:Suppress("UnstableApiUsage")
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
// 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"))
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
144
buildSrc/src/main/kotlin/BuildInfo.kt
Normal file
144
buildSrc/src/main/kotlin/BuildInfo.kt
Normal file
@@ -0,0 +1,144 @@
|
||||
@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.api.artifacts.VersionConstraint
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
|
||||
// `buildInfo` in main build scripts
|
||||
// `project.extensions.getByType<BuildInfo>()` in precompiled script plugins
|
||||
open class BuildInfo(project: Project) {
|
||||
val self = this
|
||||
|
||||
inner class GraalVm {
|
||||
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 isGraal22: Boolean by lazy {
|
||||
version.startsWith("22")
|
||||
}
|
||||
|
||||
val arch by lazy {
|
||||
if (os.isMacOsX && isGraal22) {
|
||||
"amd64"
|
||||
} else {
|
||||
self.arch
|
||||
}
|
||||
}
|
||||
|
||||
val osName: String by lazy {
|
||||
when {
|
||||
os.isMacOsX && isGraal22 -> "darwin"
|
||||
os.isMacOsX -> "macos"
|
||||
os.isLinux -> "linux"
|
||||
else -> throw RuntimeException("${os.familyName} is not supported.")
|
||||
}
|
||||
}
|
||||
|
||||
val baseName: String by lazy {
|
||||
if (graalVm.isGraal22) {
|
||||
"graalvm-ce-java11-${osName}-${arch}-${version}"
|
||||
} else {
|
||||
"graalvm-jdk-${graalVM23JdkVersion}_${osName}-${arch}_bin"
|
||||
}
|
||||
}
|
||||
|
||||
val graalVM23JdkVersion: String by lazy {
|
||||
libs.findVersion("graalVM23JdkVersion").get().requiredVersion
|
||||
}
|
||||
|
||||
val downloadUrl: String by lazy {
|
||||
if (isGraal22) {
|
||||
"https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-" +
|
||||
"${version}/$baseName.tar.gz"
|
||||
} else {
|
||||
val jdkMajor = graalVM23JdkVersion.takeWhile { it != '.' }
|
||||
"https://download.oracle.com/graalvm/$jdkMajor/archive/$baseName.tar.gz"
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
val arch: String by lazy {
|
||||
when (val arch = System.getProperty("os.arch")) {
|
||||
"x86" -> "i386"
|
||||
"x86_64" -> "amd64"
|
||||
"powerpc" -> "ppc"
|
||||
else -> arch
|
||||
}
|
||||
}
|
||||
|
||||
val graalVm: GraalVm = GraalVm()
|
||||
|
||||
val isCiBuild: Boolean by lazy {
|
||||
System.getenv("CI") != null
|
||||
}
|
||||
|
||||
val isReleaseBuild: Boolean by lazy {
|
||||
java.lang.Boolean.getBoolean("releaseBuild")
|
||||
}
|
||||
|
||||
val os: org.gradle.internal.os.OperatingSystem by lazy {
|
||||
org.gradle.internal.os.OperatingSystem.current()
|
||||
}
|
||||
|
||||
// could be `commitId: Provider<String> = project.provider { ... }`
|
||||
val commitId: String by lazy {
|
||||
// only run command once per build invocation
|
||||
if (project === project.rootProject) {
|
||||
Runtime.getRuntime()
|
||||
.exec("git rev-parse --short HEAD", arrayOf(), project.rootDir)
|
||||
.inputStream.reader().readText().trim()
|
||||
} else {
|
||||
project.rootProject.extensions.getByType(BuildInfo::class.java).commitId
|
||||
}
|
||||
}
|
||||
|
||||
val commitish: String by lazy {
|
||||
if (isReleaseBuild) project.version.toString() else commitId
|
||||
}
|
||||
|
||||
val pklVersion: String by lazy {
|
||||
if (isReleaseBuild) {
|
||||
project.version.toString()
|
||||
} else {
|
||||
project.version.toString().replace("-SNAPSHOT", "-dev+$commitId")
|
||||
}
|
||||
}
|
||||
|
||||
val pklVersionNonUnique: String by lazy {
|
||||
if (isReleaseBuild) {
|
||||
project.version.toString()
|
||||
} else {
|
||||
project.version.toString().replace("-SNAPSHOT", "-dev")
|
||||
}
|
||||
}
|
||||
|
||||
// https://melix.github.io/blog/2021/03/version-catalogs-faq.html#_but_how_can_i_use_the_catalog_in_em_plugins_em_defined_in_code_buildsrc_code
|
||||
val libs: VersionCatalog by lazy {
|
||||
project.extensions.getByType<VersionCatalogsExtension>().named("libs")
|
||||
}
|
||||
|
||||
init {
|
||||
if (!isReleaseBuild) {
|
||||
project.version = "${project.version}-SNAPSHOT"
|
||||
}
|
||||
}
|
||||
}
|
||||
47
buildSrc/src/main/kotlin/ExecutableJar.kt
Normal file
47
buildSrc/src/main/kotlin/ExecutableJar.kt
Normal file
@@ -0,0 +1,47 @@
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.listProperty
|
||||
|
||||
/**
|
||||
* Builds a self-contained Pkl CLI Jar that is directly executable on *nix
|
||||
* and executable with `java -jar` on Windows.
|
||||
*
|
||||
* For direct execution, the `java` command must be on the PATH.
|
||||
*
|
||||
* https://skife.org/java/unix/2011/06/20/really_executable_jars.html
|
||||
*/
|
||||
open class ExecutableJar : DefaultTask() {
|
||||
@get:InputFile
|
||||
val inJar: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@get:OutputFile
|
||||
val outJar: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@get:Input
|
||||
val jvmArgs: ListProperty<String> = project.objects.listProperty()
|
||||
|
||||
@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 "$@"
|
||||
""".trim().trimMargin() + "\n\n\n"
|
||||
|
||||
outFile.outputStream().use { outStream ->
|
||||
startScript.byteInputStream().use { it.copyTo(outStream) }
|
||||
inFile.inputStream().use { it.copyTo(outStream) }
|
||||
}
|
||||
|
||||
// chmod a+x
|
||||
outFile.setExecutable(true, false)
|
||||
}
|
||||
}
|
||||
7
buildSrc/src/main/kotlin/GradlePluginTests.kt
Normal file
7
buildSrc/src/main/kotlin/GradlePluginTests.kt
Normal file
@@ -0,0 +1,7 @@
|
||||
import org.gradle.util.GradleVersion
|
||||
|
||||
open class GradlePluginTests {
|
||||
lateinit var minGradleVersion: GradleVersion
|
||||
lateinit var maxGradleVersion: GradleVersion
|
||||
var skippedGradleVersions: List<GradleVersion> = listOf()
|
||||
}
|
||||
68
buildSrc/src/main/kotlin/GradleVersionInfo.kt
Normal file
68
buildSrc/src/main/kotlin/GradleVersionInfo.kt
Normal file
@@ -0,0 +1,68 @@
|
||||
import java.net.URL
|
||||
import org.gradle.util.GradleVersion
|
||||
import groovy.json.JsonSlurper
|
||||
|
||||
@Suppress("unused")
|
||||
class GradleVersionInfo(json: Map<String, Any>) {
|
||||
val version: String by json
|
||||
|
||||
val gradleVersion: GradleVersion by lazy { GradleVersion.version(version) }
|
||||
|
||||
val isReleaseVersion: Boolean by lazy {
|
||||
// for some reason, `gradleVersion == gradleVersion.baseVersion` is a compile error
|
||||
gradleVersion.version == gradleVersion.baseVersion.version
|
||||
}
|
||||
|
||||
val buildTime: String by json
|
||||
|
||||
val current: Boolean by json
|
||||
|
||||
val snapshot: Boolean by json
|
||||
|
||||
val nightly: Boolean by json
|
||||
|
||||
val releaseNightly: Boolean by json
|
||||
|
||||
val activeRc: Boolean by json
|
||||
|
||||
val rcFor: String by json
|
||||
|
||||
val milestoneFor: String by json
|
||||
|
||||
val broken: Boolean by json
|
||||
|
||||
val downloadUrl: String by json
|
||||
|
||||
val checksumUrl: String by json
|
||||
|
||||
val wrapperChecksumUrl: String by json
|
||||
|
||||
companion object {
|
||||
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 fetchRc(): GradleVersionInfo? = fetchSingleOrNull("https://services.gradle.org/versions/release-candidate")
|
||||
|
||||
fun fetchNightly(): GradleVersionInfo = fetchSingle("https://services.gradle.org/versions/nightly")
|
||||
|
||||
private fun fetchSingle(url: String): GradleVersionInfo {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return GradleVersionInfo(JsonSlurper().parse(URL(url)) as Map<String, Any>)
|
||||
}
|
||||
|
||||
private fun fetchSingleOrNull(url: String): GradleVersionInfo? {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val json = JsonSlurper().parse(URL(url)) as Map<String, Any>
|
||||
return if (json.isEmpty()) null else GradleVersionInfo(json)
|
||||
}
|
||||
|
||||
private fun fetchMultiple(url: String): List<GradleVersionInfo> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return (JsonSlurper().parse(URL(url)) as List<Map<String, Any>>)
|
||||
.map { GradleVersionInfo(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
6
buildSrc/src/main/kotlin/HtmlValidator.kt
Normal file
6
buildSrc/src/main/kotlin/HtmlValidator.kt
Normal file
@@ -0,0 +1,6 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
|
||||
open class HtmlValidator(project: Project) {
|
||||
var sources: FileCollection = project.files()
|
||||
}
|
||||
115
buildSrc/src/main/kotlin/MergeSourcesJars.kt
Normal file
115
buildSrc/src/main/kotlin/MergeSourcesJars.kt
Normal file
@@ -0,0 +1,115 @@
|
||||
import java.io.File
|
||||
import java.util.regex.Matcher
|
||||
import java.util.regex.Pattern
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.FileVisitDetails
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.MapProperty
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
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 mergedBinaryJars: ConfigurableFileCollection = project.objects.fileCollection()
|
||||
|
||||
@get:Input
|
||||
val relocatedPackages: MapProperty<String, String> = project.objects.mapProperty()
|
||||
|
||||
@get:Input
|
||||
var sourceFileExtensions: ListProperty<String> = project.objects.listProperty<String>()
|
||||
.convention(listOf(".java", ".kt"))
|
||||
|
||||
@get:OutputFile
|
||||
val outputJar: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@TaskAction
|
||||
@Suppress("unused")
|
||||
fun merge() {
|
||||
val binaryPaths = collectBinaryPaths()
|
||||
|
||||
val relocatedPkgs = relocatedPackages.get()
|
||||
|
||||
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 sourceFileExts = sourceFileExtensions.get()
|
||||
|
||||
val outDir = this.temporaryDir
|
||||
|
||||
for (jar in inputJars) {
|
||||
// as of Gradle 2.4, doesn't visit dirs despite the claims
|
||||
project.zipTree(jar).visit {
|
||||
val details = this
|
||||
if (details.isDirectory) return@visit
|
||||
|
||||
var path = details.relativePath.parent.pathString
|
||||
val relocatedPath = relocatedPaths.keys.find { path.startsWith(it) }
|
||||
if (relocatedPath != null) {
|
||||
path = path.replace(relocatedPath, relocatedPaths.getValue(relocatedPath))
|
||||
}
|
||||
// conservative shrinking
|
||||
if (!binaryPaths.contains(path)) return@visit
|
||||
|
||||
val outFile = File("$outDir/$path/${details.file.name}")
|
||||
outFile.parentFile.mkdirs()
|
||||
|
||||
if (sourceFileExts.any { details.file.name.endsWith(it) }) {
|
||||
val oldContents = details.file.readText(Charsets.UTF_8)
|
||||
val newContents = fixImports(relocatedPkgs, details, oldContents, importPattern)
|
||||
outFile.writeText(newContents, Charsets.UTF_8)
|
||||
} else {
|
||||
details.copyTo(outFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project.ant.invokeMethod("jar", mapOf("basedir" to outDir, "destfile" to outputJar.get()))
|
||||
}
|
||||
|
||||
private fun collectBinaryPaths(): Set<String> {
|
||||
val result = mutableSetOf<String>()
|
||||
for (jar in mergedBinaryJars) {
|
||||
// as of Gradle 2.4 doesn't visit dirs despite the claims
|
||||
project.zipTree(jar).visit {
|
||||
val details = this
|
||||
if (details.isDirectory) return@visit // avoid adding empty dirs
|
||||
result.add(details.relativePath.parent.pathString)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun fixImports(
|
||||
relocatedPkgs: Map<String, String>,
|
||||
details: FileVisitDetails,
|
||||
sourceText: String,
|
||||
importPattern: Pattern
|
||||
): String {
|
||||
val matcher = importPattern.matcher(sourceText)
|
||||
val buffer = StringBuffer()
|
||||
logger.debug("Inspecting file: {}", details.relativePath)
|
||||
while (matcher.find()) {
|
||||
val newStat = relocatedPkgs[matcher.group(2)]
|
||||
logger.debug("Old: {}", matcher.group())
|
||||
logger.debug("New: {}", newStat)
|
||||
matcher.appendReplacement(buffer, Matcher.quoteReplacement(newStat))
|
||||
}
|
||||
matcher.appendTail(buffer)
|
||||
return buffer.toString()
|
||||
}
|
||||
|
||||
private fun toPath(packageName: String): String = packageName.replace(".", "/")
|
||||
}
|
||||
43
buildSrc/src/main/kotlin/ResolveSourcesJars.kt
Normal file
43
buildSrc/src/main/kotlin/ResolveSourcesJars.kt
Normal file
@@ -0,0 +1,43 @@
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.result.ResolvedArtifactResult
|
||||
import org.gradle.api.artifacts.result.ResolvedDependencyResult
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.jvm.JvmLibrary
|
||||
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: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 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 }
|
||||
|
||||
// copying to an output dir because I don't know how else to describe task outputs
|
||||
project.sync {
|
||||
from(resolvedJars)
|
||||
into(outputDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
95
buildSrc/src/main/kotlin/pklAllProjects.gradle.kts
Normal file
95
buildSrc/src/main/kotlin/pklAllProjects.gradle.kts
Normal file
@@ -0,0 +1,95 @@
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
val buildInfo = extensions.create<BuildInfo>("buildInfo", project)
|
||||
|
||||
dependencyLocking {
|
||||
lockAllConfigurations()
|
||||
}
|
||||
|
||||
configurations {
|
||||
val rejectedVersionSuffix = Regex("-alpha|-beta|-eap|-m|-rc|-snapshot", RegexOption.IGNORE_CASE)
|
||||
configureEach {
|
||||
resolutionStrategy {
|
||||
componentSelection {
|
||||
all {
|
||||
if (rejectedVersionSuffix.containsMatchIn(candidate.version)) {
|
||||
reject("Rejected dependency $candidate " +
|
||||
"because it has a prelease version suffix matching `$rejectedVersionSuffix`.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plugins.withType(JavaPlugin::class).configureEach {
|
||||
val java = project.extensions.getByType<JavaPluginExtension>()
|
||||
java.sourceCompatibility = JavaVersion.VERSION_11
|
||||
java.targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile>().configureEach {
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
freeCompilerArgs = freeCompilerArgs + listOf("-Xjsr305=strict", "-Xjvm-default=all")
|
||||
}
|
||||
}
|
||||
|
||||
plugins.withType(IdeaPlugin::class).configureEach {
|
||||
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)
|
||||
}
|
||||
}
|
||||
if (project == rootProject) {
|
||||
tasks.named("ideaProject") {
|
||||
doFirst {
|
||||
throw GradleException(errorMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plugins.withType(MavenPublishPlugin::class).configureEach {
|
||||
configure<PublishingExtension> {
|
||||
// CI builds pick up artifacts from this repo.
|
||||
// It's important that this repo is only declared once per project.
|
||||
repositories {
|
||||
maven {
|
||||
name = "projectLocal" // affects task names
|
||||
url = uri("file:///$rootDir/build/m2")
|
||||
}
|
||||
}
|
||||
// use resolved/locked (e.g., `1.15`)
|
||||
// instead of declared (e.g., `1.+`)
|
||||
// dependency versions in generated POMs
|
||||
publications {
|
||||
withType(MavenPublication::class.java) {
|
||||
versionMapping {
|
||||
allVariants {
|
||||
fromResolutionResult()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 allDependencies by tasks.registering(DependencyReportTask::class)
|
||||
183
buildSrc/src/main/kotlin/pklFatJar.gradle.kts
Normal file
183
buildSrc/src/main/kotlin/pklFatJar.gradle.kts
Normal file
@@ -0,0 +1,183 @@
|
||||
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
|
||||
import org.gradle.kotlin.dsl.*
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
id("com.github.johnrengelman.shadow")
|
||||
}
|
||||
|
||||
// make fat Jar available to other subprojects
|
||||
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 relocations = mapOf(
|
||||
// pkl-core dependencies
|
||||
"org.antlr.v4." to "org.pkl.thirdparty.antlr.v4.",
|
||||
// https://github.com/oracle/graal/issues/1644 has been fixed,
|
||||
// but native-image still fails when shading com.oracle.truffle
|
||||
//"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.",
|
||||
|
||||
// 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-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-codegen-java dependencies
|
||||
"com.squareup.javapoet." to "org.pkl.thirdparty.javapoet.",
|
||||
|
||||
// pkl-codegen-kotlin dependencies
|
||||
"com.squareup.kotlinpoet." to "org.pkl.thirdparty.kotlinpoet.",
|
||||
)
|
||||
|
||||
val nonRelocations = listOf("com/oracle/truffle/")
|
||||
|
||||
tasks.shadowJar {
|
||||
inputs.property("relocations", relocations)
|
||||
|
||||
archiveClassifier.set(null as String?)
|
||||
|
||||
configurations = listOf(project.configurations.runtimeClasspath.get())
|
||||
|
||||
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("module-info.*")
|
||||
|
||||
for ((from, to) in relocations) {
|
||||
relocate(from, to)
|
||||
}
|
||||
|
||||
// necessary for service files to be adapted to relocation
|
||||
mergeServiceFiles()
|
||||
}
|
||||
|
||||
// workaround for https://github.com/johnrengelman/shadow/issues/651
|
||||
components.withType(AdhocComponentWithVariants::class.java).forEach { c ->
|
||||
c.withVariantsFromConfiguration(project.configurations.shadowRuntimeElements.get()) {
|
||||
skip()
|
||||
}
|
||||
}
|
||||
|
||||
val testFatJar by tasks.registering(Test::class) {
|
||||
testClassesDirs = files(tasks.test.get().testClassesDirs)
|
||||
classpath =
|
||||
// compiled test classes
|
||||
sourceSets.test.get().output +
|
||||
// fat Jar
|
||||
tasks.shadowJar.get().outputs.files +
|
||||
// test-only dependencies
|
||||
// (test dependencies that are also main dependencies must already be contained in fat Jar;
|
||||
// to verify that, we don't want to include them here)
|
||||
(configurations.testRuntimeClasspath.get() - configurations.runtimeClasspath.get())
|
||||
}
|
||||
|
||||
tasks.check {
|
||||
dependsOn(testFatJar)
|
||||
}
|
||||
|
||||
val validateFatJar by tasks.registering {
|
||||
val outputFile = file("$buildDir/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)
|
||||
}
|
||||
}
|
||||
if (unshadowedFiles.isEmpty()) {
|
||||
outputFile.writeText("SUCCESS")
|
||||
} else {
|
||||
outputFile.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(project.file("$buildDir/resolveSourcesJars"))
|
||||
}
|
||||
|
||||
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) })
|
||||
|
||||
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)
|
||||
|
||||
// sources Jar is fat
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
85
buildSrc/src/main/kotlin/pklGraalVm.gradle.kts
Normal file
85
buildSrc/src/main/kotlin/pklGraalVm.gradle.kts
Normal file
@@ -0,0 +1,85 @@
|
||||
import java.nio.file.*
|
||||
import java.util.UUID
|
||||
import de.undercouch.gradle.tasks.download.Download
|
||||
import de.undercouch.gradle.tasks.download.Verify
|
||||
|
||||
plugins {
|
||||
id("de.undercouch.download")
|
||||
}
|
||||
|
||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||
|
||||
val homeDir = buildInfo.graalVm.homeDir
|
||||
val baseName = buildInfo.graalVm.baseName
|
||||
val installDir = buildInfo.graalVm.installDir
|
||||
val downloadUrl = buildInfo.graalVm.downloadUrl
|
||||
val downloadFile = file(homeDir).resolve("$baseName.tar.gz")
|
||||
|
||||
// tries to minimize chance of corruption by download-to-temp-file-and-move
|
||||
val downloadGraalVm by tasks.registering(Download::class) {
|
||||
onlyIf {
|
||||
!installDir.exists()
|
||||
}
|
||||
|
||||
src(downloadUrl)
|
||||
dest(downloadFile)
|
||||
overwrite(false)
|
||||
tempAndMove(true)
|
||||
}
|
||||
|
||||
val verifyGraalVm by tasks.registering(Verify::class) {
|
||||
onlyIf {
|
||||
!installDir.exists()
|
||||
}
|
||||
|
||||
dependsOn(downloadGraalVm)
|
||||
src(downloadFile)
|
||||
checksum(buildInfo.libs.findVersion("graalVmSha256-${buildInfo.graalVm.osName}-${buildInfo.graalVm.arch}").get().toString())
|
||||
algorithm("SHA-256")
|
||||
}
|
||||
|
||||
// minimize chance of corruption by extract-to-random-dir-and-flip-symlink
|
||||
val installGraalVm by tasks.registering {
|
||||
dependsOn(verifyGraalVm)
|
||||
|
||||
onlyIf {
|
||||
!installDir.exists()
|
||||
}
|
||||
|
||||
doLast {
|
||||
val distroDir = "$homeDir/${UUID.randomUUID()}"
|
||||
|
||||
try {
|
||||
mkdir(distroDir)
|
||||
|
||||
println("Extracting $downloadFile into $distroDir")
|
||||
// faster and more reliable than Gradle's `copy { from tarTree() }`
|
||||
exec {
|
||||
workingDir = file(distroDir)
|
||||
executable = "tar"
|
||||
args("--strip-components=1", "-xzf", downloadFile)
|
||||
}
|
||||
|
||||
val distroBinDir = if (buildInfo.os.isMacOsX) "$distroDir/Contents/Home/bin" else "$distroDir/bin"
|
||||
|
||||
println("Installing native-image into $distroDir")
|
||||
exec {
|
||||
executable = "$distroBinDir/gu"
|
||||
args("install", "--no-progress", "native-image")
|
||||
}
|
||||
|
||||
println("Creating symlink $installDir for $distroDir")
|
||||
val tempLink = Paths.get("$homeDir/${UUID.randomUUID()}")
|
||||
Files.createSymbolicLink(tempLink, Paths.get(distroDir))
|
||||
try {
|
||||
Files.move(tempLink, 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
|
||||
}
|
||||
}
|
||||
}
|
||||
103
buildSrc/src/main/kotlin/pklGradlePluginTest.gradle.kts
Normal file
103
buildSrc/src/main/kotlin/pklGradlePluginTest.gradle.kts
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Allows to run Gradle plugin tests against different Gradle versions.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
java
|
||||
}
|
||||
|
||||
val gradlePluginTests = extensions.create<GradlePluginTests>("gradlePluginTests")
|
||||
|
||||
tasks.addRule("Pattern: compatibilityTest[All|Releases|Latest|Candidate|Nightly|<GradleVersion>]") {
|
||||
val taskName = this
|
||||
val matchResult = Regex("compatibilityTest(.+)").matchEntire(taskName) ?: return@addRule
|
||||
|
||||
when (val taskNameSuffix = matchResult.groupValues[1]) {
|
||||
"All" ->
|
||||
task("compatibilityTestAll") {
|
||||
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
|
||||
}
|
||||
|
||||
dependsOn(versionsToTestAgainst.map { createCompatibilityTestTask(it) })
|
||||
}
|
||||
// latest release (if not developing against latest)
|
||||
"Latest" ->
|
||||
task("compatibilityTestLatest") {
|
||||
val versionInfo = GradleVersionInfo.fetchCurrent()
|
||||
if (versionInfo.version == gradle.gradleVersion) {
|
||||
doLast {
|
||||
println("No new Gradle release available. " +
|
||||
"(Run `gradlew test` to test against ${versionInfo.version}.)")
|
||||
}
|
||||
} else {
|
||||
dependsOn(createCompatibilityTestTask(versionInfo))
|
||||
}
|
||||
}
|
||||
// active release candidate (if any)
|
||||
"Candidate" ->
|
||||
task("compatibilityTestCandidate") {
|
||||
val versionInfo = GradleVersionInfo.fetchRc()
|
||||
if (versionInfo?.activeRc == true) {
|
||||
dependsOn(createCompatibilityTestTask(versionInfo))
|
||||
} else {
|
||||
doLast {
|
||||
println("No active Gradle release candidate available.")
|
||||
}
|
||||
}
|
||||
}
|
||||
// latest nightly
|
||||
"Nightly" ->
|
||||
task("compatibilityTestNightly") {
|
||||
val versionInfo = GradleVersionInfo.fetchNightly()
|
||||
dependsOn(createCompatibilityTestTask(versionInfo))
|
||||
}
|
||||
// explicit version
|
||||
else ->
|
||||
createCompatibilityTestTask(
|
||||
taskNameSuffix,
|
||||
"https://services.gradle.org/distributions-snapshots/gradle-$taskNameSuffix-bin.zip"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun createCompatibilityTestTask(versionInfo: GradleVersionInfo): Task =
|
||||
createCompatibilityTestTask(versionInfo.version, versionInfo.downloadUrl)
|
||||
|
||||
fun createCompatibilityTestTask(version: String, downloadUrl: String): Task {
|
||||
return tasks.create("compatibilityTest$version", Test::class.java) {
|
||||
mustRunAfter(tasks.test)
|
||||
|
||||
maxHeapSize = tasks.test.get().maxHeapSize
|
||||
jvmArgs = tasks.test.get().jvmArgs
|
||||
classpath = tasks.test.get().classpath
|
||||
systemProperty("testGradleVersion", version)
|
||||
systemProperty("testGradleDistributionUrl", downloadUrl)
|
||||
|
||||
doFirst {
|
||||
if (version == gradle.gradleVersion && gradle.taskGraph.hasTask(tasks.test.get())) {
|
||||
// don't test same version twice
|
||||
println("This version has already been tested by the `test` task.")
|
||||
throw StopExecutionException()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
58
buildSrc/src/main/kotlin/pklHtmlValidator.gradle.kts
Normal file
58
buildSrc/src/main/kotlin/pklHtmlValidator.gradle.kts
Normal file
@@ -0,0 +1,58 @@
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@Suppress("UnstableApiUsage")
|
||||
validatorConfiguration(buildInfo.libs.findLibrary("nuValidator").get()) {
|
||||
// we only want jetty-util and jetty-util-ajax (with the right version)
|
||||
// couldn't find a more robust way to express this
|
||||
exclude(group = "org.eclipse.jetty", module = "jetty-continuation")
|
||||
exclude(group = "org.eclipse.jetty", module = "jetty-http")
|
||||
exclude(group = "org.eclipse.jetty", module = "jetty-io")
|
||||
exclude(group = "org.eclipse.jetty", module = "jetty-security")
|
||||
exclude(group = "org.eclipse.jetty", module = "jetty-server")
|
||||
exclude(group = "org.eclipse.jetty", module = "jetty-servlets")
|
||||
exclude(group = "javax.servlet")
|
||||
exclude(group = "commons-fileupload")
|
||||
}
|
||||
}
|
||||
|
||||
val validateHtml by tasks.registering(JavaExec::class) {
|
||||
val resultFile = file("$buildDir/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)
|
||||
|
||||
// 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.writeText("Success.") }
|
||||
}
|
||||
|
||||
tasks.check {
|
||||
dependsOn(validateHtml)
|
||||
}
|
||||
59
buildSrc/src/main/kotlin/pklJavaLibrary.gradle.kts
Normal file
59
buildSrc/src/main/kotlin/pklJavaLibrary.gradle.kts
Normal file
@@ -0,0 +1,59 @@
|
||||
@file:Suppress("HttpUrlsUsage")
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
id("pklKotlinTest")
|
||||
id("com.diffplug.spotless")
|
||||
}
|
||||
|
||||
// make sources Jar available to other subprojects
|
||||
val sourcesJarConfiguration = configurations.register("sourcesJar")
|
||||
|
||||
java {
|
||||
withSourcesJar() // creates `sourcesJar` task
|
||||
withJavadocJar()
|
||||
}
|
||||
|
||||
artifacts {
|
||||
// make sources Jar available to other subprojects
|
||||
add("sourcesJar", tasks["sourcesJar"])
|
||||
}
|
||||
|
||||
spotless {
|
||||
java {
|
||||
googleJavaFormat("1.15.0")
|
||||
targetExclude("**/generated/**", "**/build/**")
|
||||
licenseHeaderFile(rootProject.file("buildSrc/src/main/resources/license-header.star-block.txt"))
|
||||
}
|
||||
}
|
||||
|
||||
tasks.compileKotlin {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
tasks.jar {
|
||||
manifest {
|
||||
attributes += mapOf("Automatic-Module-Name" to "org.${project.name.replace("-", ".")}")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.javadoc {
|
||||
classpath = sourceSets.main.get().output + sourceSets.main.get().compileClasspath
|
||||
source = sourceSets.main.get().allJava
|
||||
title = "${project.name} ${project.version} API"
|
||||
(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.
|
||||
file("$buildDir/classes/kotlin/main").mkdirs()
|
||||
}
|
||||
}
|
||||
|
||||
tasks.compileJava {
|
||||
dependsOn(workAroundKotlinGradlePluginBug)
|
||||
}
|
||||
28
buildSrc/src/main/kotlin/pklKotlinLibrary.gradle.kts
Normal file
28
buildSrc/src/main/kotlin/pklKotlinLibrary.gradle.kts
Normal file
@@ -0,0 +1,28 @@
|
||||
plugins {
|
||||
id("pklJavaLibrary")
|
||||
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||
|
||||
dependencies {
|
||||
// At least some of our kotlin APIs contain Kotlin stdlib types
|
||||
// that aren't compiled away by kotlinc (e.g., `kotlin.Function`).
|
||||
// So let's be conservative and default to `api` for now.
|
||||
// For Kotlin APIs that only target Kotlin users (e.g., pkl-config-kotlin),
|
||||
// it won't make a difference.
|
||||
api(buildInfo.libs.findLibrary("kotlinStdLib").get())
|
||||
}
|
||||
|
||||
tasks.compileKotlin {
|
||||
enabled = true // disabled by pklJavaLibrary
|
||||
}
|
||||
|
||||
spotless {
|
||||
kotlin {
|
||||
ktfmt("0.44").googleStyle()
|
||||
targetExclude("**/generated/**", "**/build/**")
|
||||
licenseHeaderFile(rootProject.file("buildSrc/src/main/resources/license-header.star-block.txt"))
|
||||
}
|
||||
}
|
||||
57
buildSrc/src/main/kotlin/pklKotlinTest.gradle.kts
Normal file
57
buildSrc/src/main/kotlin/pklKotlinTest.gradle.kts
Normal file
@@ -0,0 +1,57 @@
|
||||
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
|
||||
import java.net.URI
|
||||
|
||||
plugins {
|
||||
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())
|
||||
|
||||
testRuntimeOnly(buildInfo.libs.findLibrary("junitEngine").get())
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
val testTask = this
|
||||
|
||||
useJUnitPlatform()
|
||||
|
||||
// enable checking of stdlib return types
|
||||
systemProperty("org.pkl.testMode", "true")
|
||||
|
||||
reports.named("html") {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
testLogging {
|
||||
exceptionFormat = TestExceptionFormat.FULL
|
||||
}
|
||||
|
||||
addTestListener(object : TestListener {
|
||||
override fun beforeSuite(suite: TestDescriptor) {}
|
||||
override fun beforeTest(testDescriptor: TestDescriptor) {}
|
||||
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
|
||||
}
|
||||
})
|
||||
}
|
||||
7
buildSrc/src/main/kotlin/pklNativeBuild.gradle.kts
Normal file
7
buildSrc/src/main/kotlin/pklNativeBuild.gradle.kts
Normal file
@@ -0,0 +1,7 @@
|
||||
val assembleNative by tasks.registering {}
|
||||
|
||||
val checkNative by tasks.registering {}
|
||||
|
||||
val buildNative by tasks.registering {
|
||||
dependsOn(assembleNative, checkNative)
|
||||
}
|
||||
118
buildSrc/src/main/kotlin/pklPublishLibrary.gradle.kts
Normal file
118
buildSrc/src/main/kotlin/pklPublishLibrary.gradle.kts
Normal file
@@ -0,0 +1,118 @@
|
||||
import org.gradle.api.publish.maven.tasks.GenerateMavenPom
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.Base64
|
||||
|
||||
plugins {
|
||||
`maven-publish`
|
||||
signing
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val validatePom by tasks.registering {
|
||||
val generatePomFileForLibraryPublication by tasks.existing(GenerateMavenPom::class)
|
||||
val outputFile = file("$buildDir/validatePom") // dummy output to satisfy up-to-date check
|
||||
|
||||
dependsOn(generatePomFileForLibraryPublication)
|
||||
inputs.file(generatePomFileForLibraryPublication.get().destination)
|
||||
outputs.file(outputFile)
|
||||
|
||||
doLast {
|
||||
outputFile.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.writeText("OK")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.publish {
|
||||
dependsOn(validatePom)
|
||||
}
|
||||
|
||||
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) }
|
||||
}
|
||||
|
||||
artifacts {
|
||||
project.tasks.findByName("javadocJar")?.let { archives(it) }
|
||||
project.tasks.findByName("sourcesJar")?.let { archives(it) }
|
||||
}
|
||||
16
buildSrc/src/main/resources/license-header.line-comment.txt
Normal file
16
buildSrc/src/main/resources/license-header.line-comment.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
15
buildSrc/src/main/resources/license-header.star-block.txt
Normal file
15
buildSrc/src/main/resources/license-header.star-block.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
6
docs/antora.yml
Normal file
6
docs/antora.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
name: main
|
||||
title: Main Project
|
||||
version: 0.25.0-dev
|
||||
prerelease: true
|
||||
nav:
|
||||
- nav.adoc
|
||||
35
docs/docs.gradle.kts
Normal file
35
docs/docs.gradle.kts
Normal file
@@ -0,0 +1,35 @@
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
|
||||
|
||||
plugins {
|
||||
pklAllProjects
|
||||
pklKotlinTest
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
test {
|
||||
java {
|
||||
srcDir(file("modules/pkl-core/examples"))
|
||||
srcDir(file("modules/pkl-config-java/examples"))
|
||||
}
|
||||
val kotlin = project.extensions
|
||||
.getByType<KotlinJvmProjectExtension>()
|
||||
.sourceSets[name]
|
||||
.kotlin
|
||||
kotlin.srcDir(file("modules/pkl-config-kotlin/examples"))
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation(project(":pkl-core"))
|
||||
testImplementation(project(":pkl-config-java"))
|
||||
testImplementation(project(":pkl-config-kotlin"))
|
||||
testImplementation(project(":pkl-commons-test"))
|
||||
testImplementation(libs.junitEngine)
|
||||
testImplementation(libs.antlrRuntime)
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
inputs.files(fileTree("modules").matching {
|
||||
include("**/pages/*.adoc")
|
||||
})
|
||||
}
|
||||
36
docs/gradle.lockfile
Normal file
36
docs/gradle.lockfile
Normal file
@@ -0,0 +1,36 @@
|
||||
# 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.14=testRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy:1.12.21=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.24.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.graalvm.sdk:graal-sdk:22.3.1=testRuntimeClasspath
|
||||
org.graalvm.truffle:truffle-api:22.3.1=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.9.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.jupiter:junit-jupiter-engine:5.9.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.jupiter:junit-jupiter-params:5.9.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.9.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit.platform:junit-platform-engine:1.9.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.junit:junit-bom:5.9.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
org.opentest4j:opentest4j:1.2.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath,testRuntimeOnlyDependenciesMetadata
|
||||
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
|
||||
8
docs/modules/ROOT/pages/community.adoc
Normal file
8
docs/modules/ROOT/pages/community.adoc
Normal file
@@ -0,0 +1,8 @@
|
||||
= Community
|
||||
:uri-github-issue: https://github.com/apple/pkl/issues
|
||||
:uri-github-discussions: https://github.com/apple/pkl/discussions
|
||||
|
||||
We'd love to hear from you!
|
||||
|
||||
* Create an {uri-github-issue}[issue]
|
||||
* Ask questions on {uri-github-discussions}[GitHub Discussions]
|
||||
14
docs/modules/ROOT/pages/examples.adoc
Normal file
14
docs/modules/ROOT/pages/examples.adoc
Normal file
@@ -0,0 +1,14 @@
|
||||
= Examples
|
||||
|
||||
:uri-github-apple: https://github.com/apple
|
||||
:uri-jvm-examples: {uri-github-apple}/pkl-jvm-examples
|
||||
:uri-go-examples: {uri-github-apple}/pkl-go-examples
|
||||
:uri-swift-examples: {uri-github-apple}/pkl-swift-examples
|
||||
:uri-k8s-examples: {uri-github-apple}/pkl-k8s-examples
|
||||
|
||||
For ready-to-go examples with full source code, see the various repositories that are available for you.
|
||||
|
||||
* {uri-jvm-examples}[pkl-jvm-examples] -- for using Pkl within the JVM
|
||||
* {uri-swift-examples}[pkl-swift-examples] -- for using Pkl with Swift
|
||||
* {uri-go-examples}[pkl-go-examples] -- for using Pkl with Go
|
||||
* {uri-k8s-examples}[pkl-k8s-examples] -- for using Pkl with Kubernetes
|
||||
15
docs/modules/ROOT/pages/index.adoc
Normal file
15
docs/modules/ROOT/pages/index.adoc
Normal file
@@ -0,0 +1,15 @@
|
||||
= User Manual
|
||||
include::../partials/component-attributes.adoc[]
|
||||
|
||||
Quick Links: xref:pkl-cli:index.adoc#installation[Installation] | xref:language-reference:index.adoc[Language Reference]
|
||||
|
||||
Pkl -- pronounced _Pickle_ -- is an embeddable configuration language which provides rich support for data templating and validation.
|
||||
It can be used from the command line, integrated in a build pipeline, or embedded in a program.
|
||||
Pkl scales from small to large, simple to complex, ad-hoc to repetitive configuration tasks.
|
||||
|
||||
xref:introduction:index.adoc[Introduction]:: Why we created Pkl and what it can do for you.
|
||||
xref:language.adoc[Language]:: Get to know the language and standard library.
|
||||
xref:language-bindings.adoc[Bindings]:: Libraries for embedding Pkl into general-purpose languages.
|
||||
xref:tools.adoc[Tools]:: CLI, Gradle plugin, code generators, and other tools.
|
||||
link:{uri-pkl-examples-repo}[Examples]:: Ready-to-go examples with full source code.
|
||||
xref:release-notes:index.adoc[Release Notes]:: What's new in each release.
|
||||
3
docs/modules/ROOT/pages/integrations.adoc
Normal file
3
docs/modules/ROOT/pages/integrations.adoc
Normal file
@@ -0,0 +1,3 @@
|
||||
= Framework Integrations
|
||||
|
||||
* xref:spring:ROOT:index.adoc[Spring (Boot) Integration]
|
||||
6
docs/modules/ROOT/pages/language-bindings.adoc
Normal file
6
docs/modules/ROOT/pages/language-bindings.adoc
Normal file
@@ -0,0 +1,6 @@
|
||||
= Language Bindings
|
||||
|
||||
* xref:java-binding:index.adoc[Java]
|
||||
* xref:kotlin-binding:index.adoc[Kotlin]
|
||||
* xref:swift:ROOT:index.adoc[Swift]
|
||||
* xref:go:ROOT:index.adoc[Go]
|
||||
5
docs/modules/ROOT/pages/language.adoc
Normal file
5
docs/modules/ROOT/pages/language.adoc
Normal file
@@ -0,0 +1,5 @@
|
||||
= Language
|
||||
|
||||
* xref:language-tutorial:index.adoc[Tutorial]
|
||||
* xref:language-reference:index.adoc[Language Reference]
|
||||
* xref:standard-library.adoc[Standard Library]
|
||||
7
docs/modules/ROOT/pages/resources.adoc
Normal file
7
docs/modules/ROOT/pages/resources.adoc
Normal file
@@ -0,0 +1,7 @@
|
||||
= Resources
|
||||
include::../partials/component-attributes.adoc[]
|
||||
|
||||
There's more to explore!
|
||||
|
||||
* Visit Pkl's repositories on https://github.com/apple?q=pkl[GitHub]
|
||||
* Browse the standard library's https://pkl-lang.org/package-docs/pkl/{pkl-version}/[API Docs]
|
||||
13
docs/modules/ROOT/pages/standard-library.adoc
Normal file
13
docs/modules/ROOT/pages/standard-library.adoc
Normal file
@@ -0,0 +1,13 @@
|
||||
= Standard Library
|
||||
include::../partials/component-attributes.adoc[]
|
||||
|
||||
The standard library is a set of Pkl modules, versioned and distributed together with the language.
|
||||
It is documented in the link:{uri-pkl-stdlib-docs-index}[API Docs].
|
||||
|
||||
To import a standard library module, use `import "pkl:<identifier>"`.
|
||||
For example, `import "pkl:json"` imports the `pkl.json` module.
|
||||
|
||||
The `pkl.base` module defines the most fundamental properties, methods, and classes for using Pkl.
|
||||
Its members are automatically available in every module and hence, it does not need to be imported.
|
||||
|
||||
The default module allowlist (`--allowed-modules`) grants access to all standard library modules.
|
||||
10
docs/modules/ROOT/pages/tools.adoc
Normal file
10
docs/modules/ROOT/pages/tools.adoc
Normal file
@@ -0,0 +1,10 @@
|
||||
= Tools
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
|
||||
* xref:pkl-cli:index.adoc[CLI]
|
||||
* xref:pkl-doc:index.adoc[Pkldoc]
|
||||
* xref:pkl-gradle:index.adoc[Gradle Plugin]
|
||||
* Editor support
|
||||
** xref:intellij:ROOT:index.adoc[IntelliJ]
|
||||
** xref:vscode:ROOT:index.adoc[VSCode]
|
||||
** xref:neovim:ROOT:index.adoc[Neovim]
|
||||
64
docs/modules/ROOT/partials/component-attributes.adoc
Normal file
64
docs/modules/ROOT/partials/component-attributes.adoc
Normal file
@@ -0,0 +1,64 @@
|
||||
// TODO: move to antora.yml once supported
|
||||
|
||||
// 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.25.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:
|
||||
|
||||
// the remaining attributes do not need to be updated regularly
|
||||
|
||||
:pkl-version: {pkl-version-no-suffix}-dev
|
||||
ifdef::is-release-version[]
|
||||
:pkl-version: {pkl-version-no-suffix}
|
||||
endif::[]
|
||||
|
||||
// use non-unique snapshot version because we have no way to determine unique snapshot version here
|
||||
:pkl-artifact-version: {pkl-version-no-suffix}-SNAPSHOT
|
||||
ifdef::is-release-version[]
|
||||
:pkl-artifact-version: {pkl-version}
|
||||
endif::[]
|
||||
|
||||
:uri-maven-docsite: https://central.sonatype.com/
|
||||
|
||||
:uri-sonatype: https://s01.oss.sonatype.org/service/local/repositories/snapshots/content/
|
||||
|
||||
:symbolic-version-name: latest
|
||||
ifdef::is-release-version[]
|
||||
:symbolic-version-name: current
|
||||
endif::[]
|
||||
:uri-pkl-docs-base: https://pkl-lang.org/package-docs
|
||||
:uri-pkl-stdlib-docs-base: {uri-pkl-docs-base}/pkl
|
||||
:uri-pkl-stdlib-docs: {uri-pkl-stdlib-docs-base}/{pkl-version}
|
||||
:uri-pkl-stdlib-docs-index: {uri-pkl-stdlib-docs}/
|
||||
|
||||
// TODO(oss): check these links when we have tags
|
||||
:github-branch: main
|
||||
ifdef::is-release-version[]
|
||||
:github-branch: v{pkl-version-no-suffix}
|
||||
endif::[]
|
||||
:uri-github-tree: https://github.com/apple/pkl/tree/{github-branch}
|
||||
:uri-pkl-stdlib-sources: {uri-github-tree}/stdlib
|
||||
|
||||
:github-releases-base: https://github.com/apple/pkl/releases
|
||||
:github-releases: {github-releases-base}/download/{pkl-artifact-version}
|
||||
|
||||
:uri-pkl-core-main-sources: {uri-github-tree}/pkl-core/src/main/java/org/pkl/core
|
||||
:uri-pkl-cli-main-sources: {uri-github-tree}/pkl-cli/src/main/kotlin/org/pkl/cli
|
||||
:uri-pkl-doc-main-sources: {uri-github-tree}/pkl-doc/src/main/kotlin/org/pkl/doc
|
||||
|
||||
// This attribute is used as language for Pkl code blocks.
|
||||
// It can then be mapped to different languages in different environments (e.g., IntelliJ vs. Antora).
|
||||
:pkl: pkl
|
||||
:pkl-expr: pkl expression
|
||||
|
||||
:uri-pkl-examples-repo: https://github.com/apple/pkl-jvm-examples
|
||||
:uri-pkl-examples-tree: {uri-pkl-examples-repo}/tree/main
|
||||
:uri-build-eval-example: {uri-pkl-examples-tree}/build-eval
|
||||
:uri-codegen-java-example: {uri-pkl-examples-tree}/codegen-java
|
||||
:uri-codegen-kotlin-example: {uri-pkl-examples-tree}/codegen-kotlin
|
||||
:uri-config-java-example: {uri-pkl-examples-tree}/config-java
|
||||
:uri-config-kotlin-example: {uri-pkl-examples-tree}/config-kotlin
|
||||
:uri-pkldoc-example: {uri-pkl-examples-tree}/pkldoc
|
||||
93
docs/modules/introduction/pages/comparison.adoc
Normal file
93
docs/modules/introduction/pages/comparison.adoc
Normal file
@@ -0,0 +1,93 @@
|
||||
= Comparison
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-jsonnet: https://jsonnet.org
|
||||
:uri-hcl: https://github.com/hashicorp/hcl
|
||||
:uri-dhall: https://dhall-lang.org
|
||||
:uri-pkl-spring: https://github.com/apple/pkl-spring
|
||||
:uri-graalvm: https://www.graalvm.org
|
||||
|
||||
Configuration is often described in a static configuration format or is generated with a general-purpose programming language.
|
||||
This page lists shortcomings of these approaches and explains how Pkl addresses them.
|
||||
Also, Pkl's strong and weak points in comparison to other configuration languages are discussed in this document.
|
||||
|
||||
[[static-config-formats]]
|
||||
== Pkl vs. Static Config Formats
|
||||
|
||||
Static configuration formats such as JSON, YAML, and XML work reasonably well for simple configuration needs.
|
||||
However, they do have some shortcomings, including:
|
||||
|
||||
. They are not very human-friendly to read and write. (JSON, XML)
|
||||
. They do not provide a way to split a large file into multiple smaller ones. (JSON, YAML)
|
||||
. They offer no way or very limited ways to abstract over repetitive configuration. (JSON, YAML, XML)
|
||||
. They do not offer standardized or widely available schema validators. (JSON, YAML)
|
||||
. They offer little or no schema-aware tooling. (JSON, YAML)
|
||||
|
||||
Pkl addresses these shortcomings as follows:
|
||||
|
||||
. It has a clutter-free and familiar syntax with nestable comments.
|
||||
. Modules can import other modules from local and remote locations.
|
||||
. Every object can act as a template for other objects.
|
||||
The standard library offers strong support for data manipulation.
|
||||
. It has strong built-in support for describing and validating configuration schemas.
|
||||
. It is designed to enable schema-aware tooling, such as REPLs and editors with code completion support.
|
||||
|
||||
[[general-purpose-langs]]
|
||||
== Pkl vs. General-purpose Languages
|
||||
|
||||
When configuration needs outgrow the capabilities of static configuration formats,
|
||||
projects often turn to generate configuration with a general-purpose programming language such as Python.
|
||||
Given enough effort, this approach can satisfy complex configuration needs.
|
||||
However, expressing configuration in a full-blown programming language does have some shortcomings, including:
|
||||
|
||||
. Reading, writing, and debugging configuration can become as challenging as reading, writing, and debugging application code.
|
||||
. The host language may not be a good fit for describing, manipulating, and abstracting over hierarchical configuration.
|
||||
. Configuration code may not visually resemble the configuration it generates.
|
||||
. The host language may not be a good fit for defining and validating configuration schemas.
|
||||
. Development environments may offer little help for developing and validating configuration written in the host language.
|
||||
. General-purpose languages are powerful and often difficult to sandbox.
|
||||
Are you certain your configuration script isn't erasing your hard disk or launching a rocket?
|
||||
|
||||
Pkl addresses these shortcomings as follows:
|
||||
|
||||
. As an expression-oriented and side-effect free language, it eliminates many potential sources of errors.
|
||||
. It is specifically designed for describing, manipulating, and abstracting over hierarchical configuration.
|
||||
. Pkl code often resembles the configuration it generates.
|
||||
. It has strong built-in support for defining and validating configuration schemas.
|
||||
. It is designed to enable advanced and schema-aware tooling.
|
||||
. It is comparatively powerless and strictly sandboxed, making fatal configuration mistakes and exploits less likely.
|
||||
Till now, we haven't spotted any Pkl script capable of erasing your hard disk.
|
||||
|
||||
[[other-config-langs]]
|
||||
== Pkl vs. Other Config Languages
|
||||
|
||||
Compared to open-source configuration languages such as link:{uri-jsonnet}[Jsonnet],
|
||||
link:{uri-hcl}[HCL], and link:{uri-dhall}[Dhall], Pkl's strong points are:
|
||||
|
||||
General::
|
||||
+
|
||||
* Pkl has a clean and familiar syntax, which makes it easier to read and learn.
|
||||
* Pkl supports writing sophisticated schemas, which enables config validation, code and documentation generation, and advanced IDE support.
|
||||
This is Pkl's most significant differentiator, and is the main reason why we created it.
|
||||
* Pkl has stronger templating capabilities than other config languages, reducing user code to the absolute minimum.
|
||||
|
||||
Embedding::
|
||||
+
|
||||
* Pkl is great for embedding into JVM applications.
|
||||
* Pkl offers modern xref:java-binding:pkl-config-java.adoc[JVM libraries] for runtime application configuration.
|
||||
* Pkl supports xref:java-binding:codegen.adoc[code generation] to enable statically typed access to configuration from programming languages.
|
||||
* Pkl integrates with third-party (link:{uri-pkl-spring}[Spring Boot]) JVM libraries and frameworks.
|
||||
|
||||
Tooling::
|
||||
+
|
||||
* Pkl has a polished xref:pkl-doc:index.adoc[documentation generator] that produces highly navigable and searchable documentation.
|
||||
* Pkl offers a xref:pkl-gradle:index.adoc[Gradle plugin] to easily integrate code evaluation, documentation generation, and code generation into your builds.
|
||||
* Pkl's native executables have a link:{uri-graalvm}[JIT compiler] that can speed up evaluation up to hundred times.
|
||||
|
||||
On the other hand, we believe that Pkl's weak points are:
|
||||
|
||||
* Pkl's native binaries are larger than those of other config languages.
|
||||
* Pkl is less known and has a smaller community than some other config languages.
|
||||
|
||||
We are working towards making Pkl overcome these weakness. Please support us in reaching this goal!
|
||||
|
||||
We hope that you will enjoy Pkl, and that you trust us to gradually improve its weak points.
|
||||
97
docs/modules/introduction/pages/concepts.adoc
Normal file
97
docs/modules/introduction/pages/concepts.adoc
Normal file
@@ -0,0 +1,97 @@
|
||||
= Concepts
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-property-list: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/PropertyLists/UnderstandXMLPlist/UnderstandXMLPlist.html
|
||||
|
||||
Let's get to know Pkl by discussing some of its concepts and features.
|
||||
|
||||
[[abstraction]]
|
||||
== Abstraction
|
||||
|
||||
Configuration tends to grow larger and more complex over time, making it increasingly difficult to understand and maintain.
|
||||
Pkl can reduce the size and complexity of configuration by
|
||||
|
||||
* describing similar configuration elements in terms of their differences
|
||||
* introducing abstractions for common configuration elements
|
||||
* separating configuration structure from configuration data
|
||||
* computing instead of enumerating configuration
|
||||
|
||||
[[evaluation]]
|
||||
== Evaluation
|
||||
|
||||
Pkl code lives in _modules_, a more fancy and general term for _files_.
|
||||
Evaluating a module produces an in-memory _data model_ that is roughly comparable to a JSON data model.
|
||||
If evaluation completes successfully, the Pkl evaluator converts the data model to an external representation and terminates with the status code zero.
|
||||
Otherwise, the evaluator prints an error message and terminates with a non-zero status code.
|
||||
|
||||
[[immutability]]
|
||||
== Immutability
|
||||
|
||||
All Pkl data is immutable.
|
||||
Manipulating a value always returns a new value, leaving the original value unchanged.
|
||||
Immutability eliminates many potential sources of errors.
|
||||
|
||||
[[isolation]]
|
||||
== Isolation
|
||||
|
||||
Evaluation of Pkl code is strictly sandboxed.
|
||||
Except for a few well-defined and well-controlled exceptions, Pkl code cannot interact with the outside world.
|
||||
Leaving aside bugs in the language implementation, the worst thing that buggy or malicious Pkl code can do is to consume CPU and memory resources until the evaluator gets killed.
|
||||
Over time, sandboxing will be further strengthened to cover fine-grained CPU and memory boxing.
|
||||
|
||||
[[rendering]]
|
||||
== Rendering
|
||||
|
||||
Converting a data model to an external representation is called _rendering_ the model.
|
||||
Pkl ships with renderers for the following data formats:
|
||||
|
||||
* JSON
|
||||
* Jsonnet
|
||||
* Pcf (a static subset of Pkl)
|
||||
* (Java) Properties
|
||||
* {uri-property-list}[Property List]
|
||||
* XML
|
||||
* YAML
|
||||
|
||||
Support for other formats can be added by writing a custom renderer in Pkl or Java.
|
||||
See xref:language-reference:index.adoc#module-output[Module Output] and xref:pkl-core:index.adoc#value-visitor[Value Visitor] for more information.
|
||||
|
||||
[[resemblance]]
|
||||
== Resemblance
|
||||
|
||||
By design, Pkl code tends to structurally and visually resemble the configuration it generates.
|
||||
This makes the code easier to read and write.
|
||||
|
||||
[[reuse]]
|
||||
== Reuse
|
||||
|
||||
Modules can reuse other modules by xref:language-reference:index.adoc#import-module[importing] them from local or remote locations.
|
||||
Imports can also be used to split up one large module into multiple smaller ones, increasing maintainability.
|
||||
A configurable security policy helps to keep imports under control.
|
||||
|
||||
[[schema]]
|
||||
== Schema
|
||||
|
||||
Configuration is structured data.
|
||||
Pkl supports -- but does not require -- to express this structure as a _configuration schema_, a set of classes defining configuration properties, their defaults, types, and constraints.
|
||||
Writing and maintaining a configuration schema takes some effort but, in return, provides these benefits:
|
||||
|
||||
* Independent evolution of configuration schema and configuration data, often by different teams (for example service providers and service consumers).
|
||||
* Automatic xref:pkl-doc:index.adoc[documentation generation].
|
||||
* Strong validation of configuration, both during development time and runtime.
|
||||
* Statically typed access to configuration from xref:java-binding:codegen.adoc[Java] and other languages through code generation.
|
||||
* Schema-aware development tools, for example REPLs and editors with code completion support.
|
||||
|
||||
[[template]]
|
||||
== Templating
|
||||
|
||||
Pkl supports writing templates for objects and entire modules.
|
||||
Templates can be repeatedly turned into concrete configuration by filling in the blanks, and -- when necessary -- overriding defaults.
|
||||
Sharing template modules over the network can streamline complex configuration tasks for entire teams, organizations, and communities.
|
||||
|
||||
[[usability]]
|
||||
== Usability
|
||||
|
||||
Everybody needs a configuration solution, but nobody wants to spend a lot of time learning it.
|
||||
To reflect this reality, Pkl has a strong focus on usability.
|
||||
For example, error messages explain causes and possible solutions and object properties maintain definition order to avoid surprises.
|
||||
We hope that this focus on usability will make Pkl accessible to a wide audience of occasional users, while still leaving room for expert users and advanced use cases.
|
||||
13
docs/modules/introduction/pages/index.adoc
Normal file
13
docs/modules/introduction/pages/index.adoc
Normal file
@@ -0,0 +1,13 @@
|
||||
= Introduction
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
|
||||
Pkl -- pronounced _Pickle_ -- is a configuration-as-code language with rich validation and tooling.
|
||||
It can be used as a command line tool, software library, or build plugin.
|
||||
Pkl scales from small to large, simple to complex, ad-hoc to recurring configuration tasks.
|
||||
|
||||
We created Pkl because we believe that configuration is best expressed in a special-purpose configuration language;
|
||||
a blend between a static configuration format, and a general-purpose programming language.
|
||||
|
||||
* xref:use-cases.adoc[Use Cases]
|
||||
* xref:concepts.adoc[Concepts]
|
||||
* xref:comparison.adoc[Comparison]
|
||||
35
docs/modules/introduction/pages/use-cases.adoc
Normal file
35
docs/modules/introduction/pages/use-cases.adoc
Normal file
@@ -0,0 +1,35 @@
|
||||
= Use Cases
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-kotlin-homepage: https://kotlinlang.org
|
||||
:uri-xml-property-lists: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/PropertyLists/UnderstandXMLPlist/UnderstandXMLPlist.html
|
||||
|
||||
Pkl is a good fit for:
|
||||
|
||||
Generating Static Configuration::
|
||||
Are you using a tool, service, or application that is configured with JSON, YAML, or any other static configuration format?
|
||||
+
|
||||
By generating this configuration with Pkl, you can reduce verbosity and increase maintainability through xref:concepts.adoc#reuse[reuse], xref:concepts.adoc#template[templating], and xref:concepts.adoc#abstraction[abstraction].
|
||||
JSON, YAML, and {uri-xml-property-lists}[XML property lists] are supported out of the box; xref:concepts.adoc#rendering[renderers] for other configuration formats can be developed and shared by anyone.
|
||||
Automatic defaults, strong validation, and sensible error messages come in reach with configuration xref:concepts.adoc#schema[schemas].
|
||||
+
|
||||
Generation can be triggered manually, by an automation pipeline, or by the target application.
|
||||
|
||||
Application Runtime Configuration::
|
||||
Are you the author of a tool, service, or application that consumes configuration?
|
||||
+
|
||||
By adopting Pkl as your "native" configuration solution (rather than, say, using it to generate JSON files), you benefit from a modern xref:java-binding:pkl-config-java.adoc[configuration library] that is safe, easy, and enjoyable to use.
|
||||
At the same time, anyone configuring your application -- whether that's your users, site reliability engineers (SREs), or yourself -- benefit from a well-defined, well-documented, and scalable configuration language.
|
||||
+
|
||||
At the time of writing, Pkl offers configuration libraries for the JVM runtime, Swift, and also for Golang.
|
||||
+
|
||||
We maintian the following libraries:
|
||||
+
|
||||
* xref:java-binding:pkl-config-java.adoc[pkl-config-java] for Java compatible languages
|
||||
* xref:kotlin-binding:pkl-config-kotlin.adoc[pkl-config-kotlin] for the {uri-kotlin-homepage}[Kotlin] language.
|
||||
* xref:swift:ROOT:index.adoc[pkl-swift] for the Swift language.
|
||||
* xref:go:ROOT:index.adoc[pkl-go] for the Go language.
|
||||
|
||||
In the future, we hope to add support for other popular languages and platforms, realizing our vision of a polyglot config solution based on a single config language.
|
||||
|
||||
<Your Use Case Here>::
|
||||
We are just getting started. Tell us about _your_ Pkl success story!
|
||||
22
docs/modules/java-binding/examples/JavaConfigExample.java
Normal file
22
docs/modules/java-binding/examples/JavaConfigExample.java
Normal file
@@ -0,0 +1,22 @@
|
||||
import org.pkl.config.java.Config;
|
||||
import org.pkl.config.java.ConfigEvaluator;
|
||||
import org.pkl.config.java.JavaType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
// the pkl/pkl-examples repo has a similar example
|
||||
public class JavaConfigExample {
|
||||
@Test
|
||||
public void usage() {
|
||||
// tag::usage[]
|
||||
Config config;
|
||||
try (var evaluator = ConfigEvaluator.preconfigured()) { // <1>
|
||||
config = evaluator.evaluateText(
|
||||
"pigeon { age = 5; diet = \"Seeds\" }"); // <2>
|
||||
}
|
||||
var pigeon = config.get("pigeon"); // <3>
|
||||
var age = pigeon.get("age").as(int.class); // <4>
|
||||
var diet = pigeon.get("diet").as(JavaType.listOf(String.class)); // <5>
|
||||
// end::usage[]
|
||||
}
|
||||
}
|
||||
180
docs/modules/java-binding/pages/codegen.adoc
Normal file
180
docs/modules/java-binding/pages/codegen.adoc
Normal file
@@ -0,0 +1,180 @@
|
||||
= 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
|
||||
|
||||
The Java source code generator takes Pkl class definitions as an input, and generates corresponding Java classes with equally named properties.
|
||||
|
||||
The benefits of code generation are:
|
||||
|
||||
* Configuration can be conveniently consumed as statically typed Java objects.
|
||||
* The entire configuration tree can be code-completed in Java IDEs.
|
||||
* Any drift between Java code and Pkl configuration structure is caught at compile time.
|
||||
|
||||
The generated classes are immutable and have component-wise implementations of `equals()`, `hashCode()`, and `toString()`.
|
||||
|
||||
== Installation
|
||||
|
||||
The code generator is offered as Gradle plugin, Java library, and CLI.
|
||||
|
||||
=== Gradle Plugin
|
||||
|
||||
See xref:pkl-gradle:index.adoc#installation[Installation] in the Gradle plugin chapter.
|
||||
|
||||
[[install-library]]
|
||||
=== Java Library
|
||||
|
||||
The `pkl-codegen-java` library is available {uri-pkl-codgen-java-maven-module}[from Maven Central].
|
||||
It requires Java 11 or higher.
|
||||
|
||||
ifndef::is-release-version[]
|
||||
NOTE: Snapshots are published to repository `{uri-sonatype}`.
|
||||
endif::[]
|
||||
|
||||
==== Gradle
|
||||
|
||||
To use the library in a Gradle project, declare the following dependency:
|
||||
|
||||
[tabs]
|
||||
====
|
||||
Groovy::
|
||||
+
|
||||
.build.gradle
|
||||
[source,groovy,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile "org.pkl-lang:pkl-codegen-java:{pkl-artifact-version}"
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url "{uri-sonatype}" }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
.build.gradle.kts
|
||||
[source,kotlin,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile("org.pkl-lang:pkl-codegen-java:{pkl-artifact-version}")
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url = uri("{uri-sonatype}") }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
====
|
||||
|
||||
==== Maven
|
||||
|
||||
To use the library in a Maven project, declare the following dependency:
|
||||
|
||||
.pom.xml
|
||||
[source,xml,subs="+attributes"]
|
||||
----
|
||||
<project>
|
||||
<dependency>
|
||||
<groupId>org.pkl-lang</groupId>
|
||||
<artifactId>pkl-codegen-java</artifactId>
|
||||
<version>{pkl-artifact-version}</version>
|
||||
</dependency>
|
||||
ifndef::is-release-build[]
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>sonatype-s01</id>
|
||||
<name>Sonatype S01</name>
|
||||
<url>{uri-sonatype}</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
endif::[]
|
||||
</project>
|
||||
----
|
||||
|
||||
[[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>>.
|
||||
|
||||
[[codegen-java-usage]]
|
||||
== Usage
|
||||
|
||||
The code generator is offered as Gradle plugin, Java library, and CLI.
|
||||
|
||||
=== Gradle Plugin
|
||||
|
||||
See xref:pkl-gradle:index.adoc#java-code-gen[Java Code Generation] in the Gradle plugin chapter.
|
||||
|
||||
=== Java Library
|
||||
|
||||
The Java library offers two APIs: a high-level API that corresponds to the CLI, and a lower-level API that provides additional features and control.
|
||||
The entry points for these APIs are `org.pkl.codegen.java.CliJavaCodeGenerator` and `org.pkl.codegen.java.JavaCodeGenerator`, respectively.
|
||||
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>`
|
||||
|
||||
`<modules>`::
|
||||
The absolute or relative URIs of the modules to generate classes for.
|
||||
Relative URIs are resolved against the working directory.
|
||||
|
||||
==== Options
|
||||
|
||||
.--generate-getters
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (flag not set) +
|
||||
Flag that indicates to generate private final fields and public getter methods instead of public final fields.
|
||||
====
|
||||
|
||||
.--generate-javadoc
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (flag not set) +
|
||||
Flag that indicates to generate Javadoc based on doc comments for Pkl modules, classes, and properties.
|
||||
====
|
||||
|
||||
.--params-annotation
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `org.pkl.config.java.mapper.Named` +
|
||||
Fully qualified name of the annotation to use on constructor parameters.
|
||||
====
|
||||
|
||||
.--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.
|
||||
====
|
||||
|
||||
.--implement-serializable
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (flag not set) +
|
||||
Whether to make generated classes implement `java.io.Serializable`.
|
||||
====
|
||||
|
||||
Common code generator options:
|
||||
|
||||
include::{partialsdir}/cli-codegen-options.adoc[]
|
||||
|
||||
Common CLI options:
|
||||
|
||||
include::../../pkl-cli/partials/cli-common-options.adoc[]
|
||||
|
||||
[[full-example]]
|
||||
== 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.
|
||||
4
docs/modules/java-binding/pages/index.adoc
Normal file
4
docs/modules/java-binding/pages/index.adoc
Normal file
@@ -0,0 +1,4 @@
|
||||
= Integration with Java
|
||||
|
||||
Pkl provides rich integration with Java. Our integration allows you to embed the Pkl runtime into your Java program, and also provides code generation from Pkl source files.
|
||||
|
||||
212
docs/modules/java-binding/pages/pkl-config-java.adoc
Normal file
212
docs/modules/java-binding/pages/pkl-config-java.adoc
Normal file
@@ -0,0 +1,212 @@
|
||||
= pkl-config-java Library
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-pkl-core-EvalException: {uri-pkl-core-main-sources}/EvalException.java
|
||||
|
||||
:uri-pkl-config-java-maven-module: {uri-maven-docsite}/artifact/org.pkl-lang/pkl-config-java-all
|
||||
:uri-pkl-config-java-main-sources: {uri-github-tree}/pkl-config-java/src/main/java/org/pkl/config/java
|
||||
:uri-pkl-config-java-test-sources: {uri-github-tree}/pkl-config-java/src/test/java/org/pkl/config/java
|
||||
:uri-pkl-config-java-test-resources: {uri-github-tree}/pkl-config-java/src/test/resources/org/pkl/config/java
|
||||
:uri-pkl-config-java-ConfigEvaluator: {uri-pkl-config-java-main-sources}/ConfigEvaluator.java
|
||||
:uri-pkl-config-java-Config: {uri-pkl-config-java-main-sources}/Config.java
|
||||
:uri-pkl-config-java-ValueMapper: {uri-pkl-config-java-main-sources}/mapper/ValueMapper.java
|
||||
:uri-pkl-config-java-Named: {uri-pkl-config-java-main-sources}/mapper/Named.java
|
||||
:uri-pkl-config-java-Conversion: {uri-pkl-config-java-main-sources}/mapper/Conversion.java
|
||||
:uri-pkl-config-java-Conversions: {uri-pkl-config-java-main-sources}/mapper/Conversions.java
|
||||
:uri-pkl-config-java-ConverterFactories: {uri-pkl-config-java-main-sources}/mapper/ConverterFactories.java
|
||||
:uri-pkl-config-java-Converter: {uri-pkl-config-java-main-sources}/mapper/Converter.java
|
||||
:uri-pkl-config-java-ConverterFactory: {uri-pkl-config-java-main-sources}/mapper/ConverterFactory.java
|
||||
:uri-pkl-config-java-PObjectToObjectByCtorTestJava: {uri-pkl-config-java-test-sources}/mapper/PObjectToObjectByCtorTest.java
|
||||
:uri-pkl-config-java-PObjectToObjectByCtorTestPkl: {uri-pkl-config-java-test-resources}/mapper/PObjectToObjectByCtorTest.pkl
|
||||
|
||||
The _pkl-config-java_ library builds upon xref:pkl-core:index.adoc[pkl-core].
|
||||
It offers a higher-level API specifically designed for consuming application runtime configuration.
|
||||
|
||||
== Installation
|
||||
|
||||
The _pkl-config-java_ library is available {uri-pkl-config-java-maven-module}[from Maven Central].
|
||||
It requires Java 11 or higher.
|
||||
|
||||
=== Gradle
|
||||
|
||||
To use the library in a Gradle project, declare the following dependency:
|
||||
|
||||
[tabs]
|
||||
====
|
||||
Groovy::
|
||||
+
|
||||
.build.gradle
|
||||
[source,groovy,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile "org.pkl-lang:pkl-config-java:{pkl-artifact-version}"
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url "{uri-sonatype}" }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
.build.gradle.kts
|
||||
[source,kotlin,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile("org.pkl-lang:pkl-config-java:{pkl-artifact-version}")
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url = uri("{uri-sonatype}") }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
====
|
||||
|
||||
Unlike `pkl-config-java`, `pkl-config-java__-all__` is a fat Jar with renamed third-party packages to avoid version conflicts.
|
||||
|
||||
=== Maven
|
||||
|
||||
To use the library in a Maven project, declare the following dependency:
|
||||
|
||||
.pom.xml
|
||||
[source,xml,subs="+attributes"]
|
||||
----
|
||||
<project>
|
||||
<dependency>
|
||||
<groupId>org.pkl-lang</groupId>
|
||||
<artifactId>pkl-config-java</artifactId>
|
||||
<version>{pkl-artifact-version}</version>
|
||||
</dependency>
|
||||
ifndef::is-release-build[]
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>sonatype-s01</id>
|
||||
<name>Sonatype S01</name>
|
||||
<url>{uri-sonatype}</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
endif::[]
|
||||
</project>
|
||||
----
|
||||
|
||||
Unlike `pkl-config-java`, `pkl-config-java__-all__` is a fat Jar with renamed third-party packages to avoid version conflicts.
|
||||
|
||||
== Usage
|
||||
|
||||
=== Consuming Configuration
|
||||
|
||||
The {uri-pkl-config-java-ConfigEvaluator}[`ConfigEvaluator`] class loads and evaluates Pkl modules.
|
||||
If evaluation succeeds, a {uri-pkl-config-java-Config}[`Config`] object is returned.
|
||||
Otherwise, an {uri-pkl-core-EvalException}[`EvalException`] with error details is thrown.
|
||||
|
||||
The returned `Config` object represents the root of the Pkl configuration tree.
|
||||
Intermediate and leaf nodes are also represented as `Config` objects.
|
||||
|
||||
`Config` objects offer methods to
|
||||
|
||||
* convert their Pkl value to a Java value of the specified type.
|
||||
* navigate to child nodes.
|
||||
|
||||
Let's see this in action:
|
||||
|
||||
[[config-evaluator-java-example]]
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::{examplesdir}/JavaConfigExample.java[tags=usage]
|
||||
----
|
||||
<1> Create a preconfigured `ConfigEvaluator`.
|
||||
To create a customized evaluator, start from `ConfigEvaluatorBuilder.preconfigured()` or `ConfigEvaluatorBuilder.unconfigured()`.
|
||||
The evaluator should be closed once it is no longer needed.
|
||||
In this example, this is done with a try-with-resources statement.
|
||||
Note that objects returned by the evaluator remain valid after calling `close()`.
|
||||
<2> Evaluate the given text.
|
||||
Other `evaluate` methods read from files, URLs, and other sources.
|
||||
If evaluation fails, an {uri-pkl-core-EvalException}[`EvalException`] is thrown.
|
||||
<3> Navigate from the config root to its `"pigeon"` child.
|
||||
<4> Navigate from `"pigeon"` to `"age"` and get the latter's value as an `int`.
|
||||
If conversion to the requested type fails, a `ConversionException` is thrown.
|
||||
<5> Navigate from `"pigeon"` to `"diet"` and get the latter's value as a `List<String>`.
|
||||
Note the use of `JavaType.listOf()` for creating a parameterized type literal.
|
||||
Similar methods exist for sets, maps, and other generic types.
|
||||
|
||||
A `ConfigEvaluator` caches module sources and evaluation results.
|
||||
To clear the cache, for example to evaluate the same module again, close the evaluator and create a new one.
|
||||
|
||||
For a ready-to-go example with full source code,
|
||||
see link:{uri-config-java-example}[config-java] in the _pkl/pkl-examples_ repository.
|
||||
|
||||
[[object-mapping]]
|
||||
=== Object Mapping
|
||||
|
||||
When a `Config` object needs to convert its Pkl value to a Java value, it delegates the conversion to {uri-pkl-config-java-ValueMapper}[`ValueMapper`].
|
||||
`ValueMapper` can convert an entire `PModule` or any part thereof.
|
||||
|
||||
A `ValueMapper` instance can be configured with many different Pkl-to-Java value conversions.
|
||||
`ValueMapper.preconfigured()` creates an instance configured with conversions from Pkl values to:
|
||||
|
||||
* Number types
|
||||
* Strings
|
||||
* Enums
|
||||
* Collections
|
||||
* Arrays
|
||||
* `java.util.Optional`
|
||||
* `java.time.Duration`
|
||||
* `java.net.URI/URL`
|
||||
* etc.
|
||||
|
||||
Additionally, a preconfigured `ValueMapper` instance can convert Pkl objects to Java objects with equally named properties that are settable through a constructor.
|
||||
This conversion works as follows:
|
||||
|
||||
. Find the Java class constructor with the highest number of parameters.
|
||||
. Match constructor parameters with Pkl object properties by name.
|
||||
+
|
||||
Unmatched constructor parameters result in a conversion error.
|
||||
Unmatched Pkl object properties are ignored.
|
||||
+
|
||||
. Convert each Pkl property value to the corresponding constructor parameter's type.
|
||||
. Invoke the constructor.
|
||||
|
||||
The Pkl object's runtime type is irrelevant to this conversion.
|
||||
Hence, typed and dynamic Pkl objects are equally supported.
|
||||
|
||||
To perform this conversion, `ValueMapper` needs a way to obtain the Java constructor's parameter names.
|
||||
They need to be provided in one of the following ways:
|
||||
|
||||
* Annotate constructor with `java.beans.ConstructorProperties`.
|
||||
* Annotate parameters with {uri-pkl-config-java-Named}[`Named`].
|
||||
* Annotate parameters with `javax.inject.Named`.
|
||||
* Set the Java compiler flag `-parameters`.
|
||||
|
||||
For a complete object mapping example, see:
|
||||
|
||||
* {uri-pkl-config-java-PObjectToObjectByCtorTestJava}[`PObjectToObjectByCtorTest.java`]
|
||||
|
||||
TIP: Together with xref:java-binding:codegen.adoc[code generation], object mapping provides a complete solution for consuming Pkl configuration as statically typed Java objects.
|
||||
Java code never drifts from the configuration structure defined in Pkl, and the entire configuration tree can be code-completed in Java IDEs.
|
||||
|
||||
==== Value Conversions
|
||||
|
||||
The Pkl-to-Java value conversions that ship with the library are defined in {uri-pkl-config-java-Conversions}[`Conversions`] (for individual conversions) and {uri-pkl-config-java-ConverterFactories}[`ConverterFactories`] (for families of conversions).
|
||||
To implement and register your own conversions, follow these steps:
|
||||
|
||||
. For conversions from a single source type to a single target type, implement a {uri-pkl-config-java-Conversion}[`Conversion`].
|
||||
+
|
||||
Example: `Conversions.pStringToCharacter` converts a single-character `pkl.base#String` to `java.lang.Character`.
|
||||
|
||||
. For conversions from one or multiple source types to one or multiple target types, implement a {uri-pkl-config-java-ConverterFactory}[`ConverterFactory`].
|
||||
+
|
||||
Example: `ConverterFactories.pCollectionToCollection` converts any `pkl.base#Collection` to any implementation of `java.util.Collection<E>`, for any `E`.
|
||||
+
|
||||
Converter factories are called once per combination of source type and (possibly parameterized) target type.
|
||||
The returned `Converter`s are cached.
|
||||
|
||||
. Create a `ValueMapperBuilder`, add all desired conversions, and build a `ValueMapper`.
|
||||
|
||||
. Either use the `ValueMapper` directly, or connect it to a `ConfigEvaluator` through `ConfigEvaluatorBuilder`.
|
||||
|
||||
== Further Information
|
||||
|
||||
Refer to the Javadoc and sources published with the library, or browse the library's {uri-pkl-config-java-main-sources}[main] and {uri-pkl-config-java-test-sources}[test] sources.
|
||||
23
docs/modules/java-binding/partials/cli-codegen-options.adoc
Normal file
23
docs/modules/java-binding/partials/cli-codegen-options.adoc
Normal file
@@ -0,0 +1,23 @@
|
||||
.--indent
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `" "` (two spaces) +
|
||||
Example: `"\t"` (one tab) +
|
||||
The characters to use for indenting generated source code.
|
||||
====
|
||||
|
||||
.-o, --output-dir
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (not set) +
|
||||
Example: `generated/` +
|
||||
The directory where generated source code is placed.
|
||||
Relative paths are resolved against the working directory.
|
||||
====
|
||||
|
||||
.--generate-spring-boot
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (not set) +
|
||||
Flag that indicates to generate config classes for use with Spring Boot.
|
||||
====
|
||||
33
docs/modules/kotlin-binding/examples/KotlinConfigExample.kt
Normal file
33
docs/modules/kotlin-binding/examples/KotlinConfigExample.kt
Normal file
@@ -0,0 +1,33 @@
|
||||
@file:Suppress("UNUSED_VARIABLE")
|
||||
|
||||
import org.pkl.config.java.ConfigEvaluator
|
||||
import org.pkl.config.kotlin.forKotlin
|
||||
import org.pkl.config.kotlin.to
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
// the pkl/pkl-examples repo has a similar example
|
||||
class KotlinConfigExample {
|
||||
@Test
|
||||
fun usage() {
|
||||
// tag::usage[]
|
||||
val evaluator = ConfigEvaluator.preconfigured().forKotlin() // <1>
|
||||
val config = evaluator.use { // <2>
|
||||
it.evaluateText("""pigeon { age = 5; diet = "Seeds" }""")
|
||||
}
|
||||
val pigeon = config["pigeon"] // <3>
|
||||
val age = pigeon["age"].to<Int>() // <4>
|
||||
val hobbies = pigeon["diet"].to<List<String>>() // <5>
|
||||
// end::usage[]
|
||||
}
|
||||
|
||||
@Test
|
||||
fun nullable() {
|
||||
// tag::nullable[]
|
||||
val evaluator = ConfigEvaluator.preconfigured().forKotlin()
|
||||
val config = evaluator.use {
|
||||
it.evaluateText("name = null") // <1>
|
||||
}
|
||||
val name = config["name"].to<String?>() // <2>
|
||||
// end::nullable[]
|
||||
}
|
||||
}
|
||||
130
docs/modules/kotlin-binding/pages/codegen.adoc
Normal file
130
docs/modules/kotlin-binding/pages/codegen.adoc
Normal file
@@ -0,0 +1,130 @@
|
||||
= 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
|
||||
|
||||
The Kotlin source code generator reads Pkl classes and generates corresponding Kotlin classes with equally named properties.
|
||||
|
||||
Together with xref:java-binding:pkl-config-java.adoc#object-mapping[Object Mapping], code generation provides a complete solution for consuming Pkl configuration as statically typed Kotlin objects.
|
||||
Kotlin code never drifts from the configuration structure defined in Pkl, and the entire configuration tree can be code-completed in Kotlin IDEs.
|
||||
|
||||
== Installation
|
||||
|
||||
The code generator is offered as Gradle plugin, Java library, and CLI.
|
||||
|
||||
=== Gradle Plugin
|
||||
|
||||
See xref:pkl-gradle:index.adoc#installation[Installation] in the Gradle plugin chapter.
|
||||
|
||||
[[install-library]]
|
||||
=== Java Library
|
||||
|
||||
The `pkl-codegen-kotlin` library is available {uri-pkl-codegen-kotlin-maven-module}[from Maven Central].
|
||||
It requires Java 8 or higher and Kotlin 1.3 or higher.
|
||||
|
||||
==== Gradle
|
||||
|
||||
To use the library in a Gradle project, declare the following dependency:
|
||||
|
||||
[tabs]
|
||||
====
|
||||
Groovy::
|
||||
+
|
||||
.build.gradle
|
||||
[source,groovy,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile "org.pkl-lang:pkl-config-kotlin:{pkl-artifact-version}"
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url "{uri-sonatype}" }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
.build.gradle.kts
|
||||
[source,kotlin,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile("org.pkl-lang:pkl-config-kotlin:{pkl-artifact-version}")
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url = uri("{uri-sonatype}") }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
====
|
||||
|
||||
==== Maven
|
||||
|
||||
To use the library in a Maven project, declare the following dependency:
|
||||
|
||||
.pom.xml
|
||||
[source,xml,subs="+attributes"]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.pkl-lang</groupId>
|
||||
<artifactId>pkl-codegen-kotlin</artifactId>
|
||||
<version>{pkl-artifact-version}</version>
|
||||
</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>>.
|
||||
|
||||
[[usage]]
|
||||
== Usage
|
||||
|
||||
The code generator is offered as Gradle plugin, Java library, and CLI.
|
||||
|
||||
=== Gradle Plugin
|
||||
|
||||
See xref:pkl-gradle:index.adoc#kotlin-code-gen[Kotlin Code Generation] in the Gradle plugin chapter.
|
||||
|
||||
=== Java Library
|
||||
|
||||
The library offers two APIs: a high-level API that corresponds to the CLI, and a lower-level API that provides additional features and control.
|
||||
The entry points for these APIs are `org.pkl.codegen.kotlin.CliKotlinCodeGenerator` and `org.pkl.codegen.kotlin.KotlinCodeGenerator`, respectively.
|
||||
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>`
|
||||
|
||||
`<modules>`::
|
||||
The absolute or relative URIs of the modules to generate classe for.
|
||||
Relative URIs are resolved against the working directory.
|
||||
|
||||
==== Options
|
||||
|
||||
.--generate-kdoc
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (flag not set) +
|
||||
Flag that indicates to generate Kdoc based on doc comments for Pkl modules, classes, and properties.
|
||||
====
|
||||
|
||||
Common code generator options:
|
||||
|
||||
include::../../java-binding/partials/cli-codegen-options.adoc[]
|
||||
|
||||
Common CLI options:
|
||||
|
||||
include::../../pkl-cli/partials/cli-common-options.adoc[]
|
||||
|
||||
[[full-example]]
|
||||
== 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.
|
||||
3
docs/modules/kotlin-binding/pages/index.adoc
Normal file
3
docs/modules/kotlin-binding/pages/index.adoc
Normal file
@@ -0,0 +1,3 @@
|
||||
= Integration with Kotlin
|
||||
|
||||
Pkl provides rich integration with Kotlin. Our integration allows you to embed the Pkl runtime into your Kotlin application, and also provides code generation for from Pkl source code.
|
||||
117
docs/modules/kotlin-binding/pages/pkl-config-kotlin.adoc
Normal file
117
docs/modules/kotlin-binding/pages/pkl-config-kotlin.adoc
Normal file
@@ -0,0 +1,117 @@
|
||||
= pkl-config-kotlin Library
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-pkl-config-kotlin-maven-module: {uri-maven-docsite}/artifact/org.pkl-lang/pkl-config-kotlin
|
||||
:uri-pkl-config-kotlin-main-sources: {uri-github-tree}/pkl-config-kotlin/src/main/kotlin/org/pkl/kotlin
|
||||
:uri-pkl-config-kotlin-test-sources: {uri-github-tree}/pkl-config-kotlin/src/test/kotlin/org/pkl/kotlin
|
||||
:uri-pkl-config-kotlin-ConverterFactories: {uri-pkl-config-kotlin-main-sources}/ConverterFactories.kt
|
||||
:uri-pkl-config-kotlin-ConfigExtensions: {uri-pkl-config-kotlin-main-sources}/ConfigExtensions.kt
|
||||
|
||||
The _pkl-config-kotlin_ library extends xref:java-binding:pkl-config-java.adoc[pkl-config-java] with Kotlin specific extension methods and object converters.
|
||||
We recommend that Kotlin projects depend on this library instead of _pkl-config-java_.
|
||||
|
||||
== Installation
|
||||
|
||||
The _pkl-config-kotlin_ library is available {uri-pkl-config-kotlin-maven-module}[from Maven Central].
|
||||
It requires Java 11 or higher and Kotlin 1.5 or higher.
|
||||
|
||||
=== Gradle
|
||||
|
||||
To use the library in a Gradle project, declare the following dependency:
|
||||
|
||||
[tabs]
|
||||
====
|
||||
Groovy::
|
||||
+
|
||||
.build.gradle
|
||||
[source,groovy,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile "org.pkl-lang:pkl-config-kotlin:{pkl-artifact-version}"
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url "{uri-sonatype}" }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
.build.gradle.kts
|
||||
[source,kotlin,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile("org.pkl-lang:pkl-config-kotlin:{pkl-artifact-version}")
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url = uri("{uri-sonatype}") }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
====
|
||||
|
||||
=== Maven
|
||||
|
||||
To use the library in a Maven project, declare the following dependency:
|
||||
|
||||
.pom.xml
|
||||
[source,xml,subs="+attributes"]
|
||||
----
|
||||
<project>
|
||||
<dependency>
|
||||
<groupId>org.pkl-lang</groupId>
|
||||
<artifactId>pkl-config-kotlin</artifactId>
|
||||
<version>{pkl-artifact-version}</version>
|
||||
</dependency>
|
||||
ifndef::is-release-build[]
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>sonatype-s01</id>
|
||||
<name>Sonatype S01</name>
|
||||
<url>{uri-sonatype}</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
endif::[]
|
||||
</project>
|
||||
----
|
||||
|
||||
== Usage
|
||||
|
||||
Below is the Kotlin version of the Java xref:java-binding:pkl-config-java.adoc#config-evaluator-java-example[ConfigEvaluator] example.
|
||||
Differences to the Java version are called out.
|
||||
|
||||
[source,kotlin,indent=0]
|
||||
----
|
||||
include::{examplesdir}/KotlinConfigExample.kt[tags=usage]
|
||||
----
|
||||
<1> Use the `forKotlin()` method to preconfigure the builder with Kotlin specific conversions.
|
||||
In particular, `forKotlin()` eliminates the need to annotate constructor parameters of Kotlin classes and Kotlin data classes with `@Named`.
|
||||
<2> The evaluator should be closed once it is no longer needed.
|
||||
Here this is done with a Kotlin `use {}` expression.
|
||||
Any data returned by the evaluator before calling `close()` remains valid.
|
||||
<3> Navigate to the `"pigeon"` child.
|
||||
The subscript notation is shorthand for `config.get("pigeon")`.
|
||||
<4> Convert `"age"` to `Int` with the `Config.to()` extension method.
|
||||
The target type is provided as a type argument.
|
||||
Always use `Config.to()` instead of `Config.as()` in Kotlin.
|
||||
<5> `Config.to()` makes conversions to parameterized types straightforward:
|
||||
`to<List<String>>()` instead of `as(JavaType.listOf(String::class.java))`.
|
||||
|
||||
For properties that are allowed to be `null`, convert to a nullable type:
|
||||
|
||||
[source,kotlin,indent=0]
|
||||
----
|
||||
include::{examplesdir}/KotlinConfigExample.kt[tags=nullable]
|
||||
----
|
||||
<1> To indicate that `null` is an allowed value, convert to the nullable type `String?`.
|
||||
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.
|
||||
|
||||
== Further Information
|
||||
|
||||
Refer to the Javadoc and sources published with the library, or browse the library's {uri-pkl-config-kotlin-main-sources}[main] and {uri-pkl-config-kotlin-test-sources}[test] sources.
|
||||
5325
docs/modules/language-reference/pages/index.adoc
Normal file
5325
docs/modules/language-reference/pages/index.adoc
Normal file
File diff suppressed because it is too large
Load Diff
BIN
docs/modules/language-tutorial/images/pclHubRio.png
Normal file
BIN
docs/modules/language-tutorial/images/pclHubRio.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
317
docs/modules/language-tutorial/pages/01_basic_config.adoc
Normal file
317
docs/modules/language-tutorial/pages/01_basic_config.adoc
Normal file
@@ -0,0 +1,317 @@
|
||||
= Basic Configuration
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
|
||||
In this first part of xref:index.adoc[the Pkl tutorial], you build familiarity with Pkl syntax and basic structure.
|
||||
You also learn different ways to invoke Pkl to produce different formats.
|
||||
|
||||
== Basic values
|
||||
|
||||
Consider the following example Pkl file.
|
||||
|
||||
[source,{pkl}]
|
||||
.intro.pkl
|
||||
----
|
||||
name = "Pkl: Configure your Systems in New Ways"
|
||||
attendants = 100
|
||||
isInteractive = true
|
||||
amountLearned = 13.37
|
||||
----
|
||||
|
||||
Running Pkl on this file gives
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
$ pkl eval /Users/me/tutorial/intro.pkl
|
||||
name = "Pkl: Configure your Systems in New Ways"
|
||||
attendants = 100
|
||||
isInteractive = true
|
||||
amountLearned = 13.37
|
||||
----
|
||||
|
||||
It may seem nothing happened.
|
||||
However, Pkl tells you that it _accepts the input_.
|
||||
In other words, you now know that `intro.pkl` does not contain any errors.
|
||||
|
||||
You can ask Pkl to print this configuration in a different format, using the `-f` option.
|
||||
For example, JSON:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
$ pkl eval -f json /Users/me/tutorial/intro.pkl
|
||||
{
|
||||
"name": "Pkl: Configure your Systems in New Ways",
|
||||
"attendants": 100,
|
||||
"isInteractive": true,
|
||||
"amountLearned": 13.37
|
||||
}
|
||||
----
|
||||
|
||||
Or _PropertyList_ format:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
$ pkl eval -f plist /Users/me/tutorial/intro.pkl
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Pkl: Configure your Systems in New Ways</string>
|
||||
<key>attendants</key>
|
||||
<integer>100</integer>
|
||||
<key>isInteractive</key>
|
||||
<true/>
|
||||
<key>amountLearned</key>
|
||||
<real>13.37</real>
|
||||
</dict>
|
||||
</plist>
|
||||
----
|
||||
|
||||
Notice that Pkl generated `<string>`, `<integer>`, `<true/>` and `<real>` for the values in your configuration.
|
||||
This means it has _both_ correctly derived the types of the literal values _and_ translated those types to the corresponding elements in the PropertyList.
|
||||
xref:03_writing_a_template.adoc[Part III] goes into types in more detail.
|
||||
|
||||
|
||||
== Structure: Classes, objects, modules
|
||||
|
||||
A configuration often requires more than just basic values.
|
||||
Typically, you need some kind of (hierarchical) structure.
|
||||
Pkl provides _immutable objects_ for this.
|
||||
|
||||
Objects have three kinds of members: properties, elements and entries.
|
||||
First, look at the syntax for objects and their members.
|
||||
|
||||
=== Properties
|
||||
|
||||
[source,{pkl}]
|
||||
.simpleObjectWithProperties.pkl
|
||||
----
|
||||
bird { // <1>
|
||||
name = "Common wood pigeon" // <2>
|
||||
diet = "Seeds"
|
||||
taxonomy { // <3>
|
||||
species = "Columba palumbus"
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> This _defines_ `bird` to be an object
|
||||
<2> For primitive values, Pkl has the `=` syntax (more on this later).
|
||||
<3> Just like `bird {`, but to show that objects can be nested.
|
||||
|
||||
This defines an object called `bird` with three _named properties_: `name`, `diet`, and `taxonomy`.
|
||||
The first two of these are strings, but `taxonomy` is another object.
|
||||
This means properties in an object can have different types and objects can be nested.
|
||||
|
||||
=== Elements
|
||||
|
||||
Of course, you don't always have names for every individual structure in your configuration.
|
||||
What if you want "just a bunch of things" without knowing how many?
|
||||
Pkl offers _elements_ for this purpose.
|
||||
Elements are object members, just like properties.
|
||||
Where you index properties by their name, you index elements by an integer.
|
||||
You can think of an object that only contains elements as _array_.
|
||||
Much like arrays in many languages, you can use square brackets to access an element, for example, `myObject[42]`.
|
||||
|
||||
You write an element, by writing only an expression.
|
||||
Pkl derives the index from the number of elements already in the object.
|
||||
For example:
|
||||
|
||||
[source,{pkl}]
|
||||
.simpleObjectsWithElements.pkl
|
||||
----
|
||||
exampleObjectWithJustIntElements {
|
||||
100 // <1>
|
||||
42
|
||||
}
|
||||
|
||||
exampleObjectWithMixedElements {
|
||||
"Bird Breeder Conference"
|
||||
(2000 + 23) // <2>
|
||||
exampleObjectWithJustIntElements // <3>
|
||||
}
|
||||
----
|
||||
<1> When you write only the value (without a name), you describe an _element_.
|
||||
<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
|
||||
|
||||
Objects can have one more kind of member; _entries_.
|
||||
Like a _property_, an _entry_ is "named" (technically _keyed_).
|
||||
Unlike a property, the name does not need to be known at declaration time.
|
||||
Of course, we need a syntax to tell entries apart from properties.
|
||||
You write entry "names" by enclosing them in square brackets ("names" is quoted, because the names do not need to be strings; any value can index entries).
|
||||
|
||||
[source,{pkl}]
|
||||
.simpleObjectsWithEntries.pkl
|
||||
----
|
||||
pigeonShelter {
|
||||
["bird"] { // <1>
|
||||
name = "Common wood pigeon"
|
||||
diet = "Seeds"
|
||||
taxonomy {
|
||||
species = "Columba palumbus"
|
||||
}
|
||||
}
|
||||
["address"] = "355 Bird St." // <2>
|
||||
}
|
||||
|
||||
birdCount {
|
||||
[pigeonShelter] = 42 // <3>
|
||||
}
|
||||
----
|
||||
<1> The difference with properties is the notation of the key: `[<expression>]`.
|
||||
<2> As with properties, entries can be primitive values or objects.
|
||||
<3> Any object can be used as a key for an entry.
|
||||
|
||||
|
||||
=== Mixed members
|
||||
|
||||
In the examples so far, you have seen objects with properties, object with elements and object with entries.
|
||||
These object members can be freely mixed.
|
||||
|
||||
[source,{pkl}]
|
||||
.mixedObject.pkl
|
||||
----
|
||||
mixedObject {
|
||||
name = "Pigeon"
|
||||
lifespan = 8
|
||||
"wing"
|
||||
"claw"
|
||||
["wing"] = "Not related to the _element_ \"wing\""
|
||||
42
|
||||
extinct = false
|
||||
[false] {
|
||||
description = "Construed object example"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Notice, how properties (`name`, `lifespan` and `extinct`), elements (`"wing"`, `"claw"`, `42`) and entries (`"wing"`, `false`) are mixed together in this one object.
|
||||
You don't have to order them by kind, and you don't require (other) special syntax.
|
||||
|
||||
=== Collections
|
||||
|
||||
This free-for-all mixing of object members can become confusing.
|
||||
Also, target formats are often considerably more restrictive.
|
||||
In the following example, you see what happens when you try to produce JSON from `mixedObject`:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
$ pkl eval -f json /Users/me/tutorial/mixedObject.pkl
|
||||
–– Pkl Error ––
|
||||
Cannot render object with both properties/entries and elements as JSON.
|
||||
Object: "Pigeon"
|
||||
|
||||
89 | text = renderer.renderDocument(value)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
at pkl.base#Module.output.text (https://github.com/apple/pkl/blob/0.24.0/stdlib/base.pkl#L90)
|
||||
----
|
||||
|
||||
This is why Pkl has two special types of object, namely _listings_, which contain _exclusively_ elements, and _mappings_, which contain _exclusively_ entries.
|
||||
Both listings and mappings _are_ "just objects," so, they don't require syntax besides that of objects:
|
||||
|
||||
[source,{pkl}]
|
||||
.collections.pkl
|
||||
----
|
||||
birds { // <1>
|
||||
"Pigeon"
|
||||
"Parrot"
|
||||
"Barn owl"
|
||||
"Falcon"
|
||||
}
|
||||
|
||||
habitats { // <2>
|
||||
["Pigeon"] = "Streets"
|
||||
["Parrot"] = "Parks"
|
||||
["Barn owl"] = "Forests"
|
||||
["Falcon"] = "Mountains"
|
||||
}
|
||||
----
|
||||
<1> A listing containing four elements.
|
||||
<2> A mapping containing four entries.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
_Technically_, the correct way to define `birds` and `habitats` is by using `new Listing {...}` and `new Mapping {...}` explicitly.
|
||||
You will see what these mean in part xref:03_writing_a_template.adoc[three] of this tutorial.
|
||||
====
|
||||
|
||||
When you render _this_ configuration as JSON, everything works:
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"birds": [
|
||||
"Pigeon",
|
||||
"Parrot",
|
||||
"Barn owl",
|
||||
"Falcon"
|
||||
],
|
||||
"habitats": {
|
||||
"Pigeon": "Streets",
|
||||
"Parrot": "Parks",
|
||||
"Barn owl": "Forests",
|
||||
"Falcon": "Mountains"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Notice particularly, that you rendered the listing as a JSON _array_.
|
||||
When you index the listing with an integer, you're referring to the element inside the listing at the corresponding position (starting from `0`).
|
||||
For example:
|
||||
|
||||
[source,{pkl}]
|
||||
.indexedListing.pkl
|
||||
----
|
||||
birds {
|
||||
"Pigeon"
|
||||
"Parrot"
|
||||
"Barn owl"
|
||||
"Falcon"
|
||||
}
|
||||
|
||||
relatedToSnowOwl = birds[2]
|
||||
----
|
||||
results in
|
||||
[source,{pkl}]
|
||||
----
|
||||
birds {
|
||||
"Pigeon"
|
||||
"Parrot"
|
||||
"Barn owl"
|
||||
"Falcon"
|
||||
}
|
||||
relatedToSnowOwl = "Barn owl"
|
||||
----
|
||||
|
||||
== Exercises
|
||||
|
||||
1. Given the following JSON snippet (taken from W3C examples), write the `.pkl` file that produces this JSON:
|
||||
|
||||
+
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"name": "Common wood pigeon",
|
||||
"lifespan": 8,
|
||||
"friends": {
|
||||
"bird1": "Parrot",
|
||||
"bird2": "Albatross",
|
||||
"bird3": "Falcon"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
2. For some reason, we decide we no longer need the birdX names of the different birds; we just need them as an array.
|
||||
Change your solution to the previous question to produce the following JSON result:
|
||||
|
||||
+
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"name": "Common wood pigeon",
|
||||
"lifespan": 8,
|
||||
"birds": ["Parrot", "Barn owl", "Falcon"]
|
||||
}
|
||||
----
|
||||
@@ -0,0 +1,438 @@
|
||||
= Filling out a Template
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
|
||||
In this second part of xref:index.adoc[the Pkl tutorial], you will learn how to write one (part of a) configuration in terms of another.
|
||||
You will also find and fill out an existing _template_.
|
||||
|
||||
== Composing configurations
|
||||
=== Amending
|
||||
|
||||
The central mechanism in Pkl for expressing one (part of a) configuration in terms of another is _amending_.
|
||||
Consider the following example.
|
||||
|
||||
[source,{pkl}]
|
||||
.amendingObjects.pkl
|
||||
----
|
||||
bird {
|
||||
name = "Pigeon"
|
||||
diet = "Seeds"
|
||||
taxonomy {
|
||||
kingdom = "Animalia"
|
||||
clade = "Dinosauria"
|
||||
order = "Columbiformes"
|
||||
}
|
||||
}
|
||||
|
||||
parrot = (bird) {
|
||||
name = "Parrot"
|
||||
diet = "Berries"
|
||||
taxonomy {
|
||||
order = "Psittaciformes"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Parrot and Pigeon have nearly identical properties.
|
||||
They only differ in their name and taxonomy, so if you have already written out `bird`, you can say that `parrot` is just like `pigeon` except `name` is `"Parrot"`, diet is `"Berries"` the `taxonomy.order` is `"Psittaciformes"`.
|
||||
When you run this, Pkl expands everything fully.
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
bird {
|
||||
name = "Common wood pigeon"
|
||||
diet = "Seeds"
|
||||
taxonomy {
|
||||
kingdom = "Animalia"
|
||||
clade = "Dinosauria"
|
||||
order = "Columbiformes"
|
||||
}
|
||||
}
|
||||
parrot {
|
||||
name = "Parrot"
|
||||
diet = "Berries"
|
||||
taxonomy {
|
||||
kingdom = "Animalia"
|
||||
clade = "Dinosauria"
|
||||
order = "Psittaciformes"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
[IMPORTANT]
|
||||
====
|
||||
_Amending_ does not allow us to _add_ properties to the (typed) object we are amending.
|
||||
The xref:03_writing_a_template.adoc[next part of the tutorial] discusses types in more detail.
|
||||
There, you see that amending _never changes the type_ of the object.
|
||||
====
|
||||
|
||||
You can also amend nested objects.
|
||||
This allows you to only describe the difference with the outermost object for arbitrarily deeply nested structures.
|
||||
Consider the following example.
|
||||
|
||||
[source,{pkl}]
|
||||
.nestedAmends.pkl
|
||||
----
|
||||
woodPigeon {
|
||||
name = "Common wood pigeon"
|
||||
diet = "Seeds"
|
||||
taxonomy {
|
||||
species = "Columba palumbus"
|
||||
}
|
||||
}
|
||||
|
||||
stockPigeon = (woodPigeon) {
|
||||
name = "Stock pigeon"
|
||||
taxonomy { // <1>
|
||||
species = "Columba oenas"
|
||||
}
|
||||
}
|
||||
|
||||
dodo = (stockPigeon) { // <2>
|
||||
name = "Dodo"
|
||||
extinct = true // <3>
|
||||
taxonomy {
|
||||
species = "Raphus cucullatus"
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> This amends `species`, _as it occurs in_ `stockPigeon`.
|
||||
<2> Amended objects can, themselves, be amended.
|
||||
<3> New fields can be added to objects when amending.
|
||||
|
||||
Notice how you only have to change `taxonomy.species`.
|
||||
In this example, `bird.taxonomy` has `kingdom`, `clade`, `order` and `species`.
|
||||
You are amending `stockPigeon`, to define `woodPigeon`.
|
||||
They have the same `taxonomy`, except for `species`.
|
||||
This notation says that everything in `taxonomy` should be what it is in the object you are amending (`stockPigeon`), except for `species`, which should be `"Columba palumbus"` .
|
||||
|
||||
For the input above, Pkl produces the following output.
|
||||
[source,{pkl}]
|
||||
----
|
||||
woodPigeon {
|
||||
name = "Common wood pigeon"
|
||||
diet = "Seeds"
|
||||
taxonomy {
|
||||
species = "Columba palumbus"
|
||||
}
|
||||
}
|
||||
stockPigeon {
|
||||
name = "Stock pigeon"
|
||||
diet = "Seeds"
|
||||
taxonomy {
|
||||
species = "Columba oenas"
|
||||
}
|
||||
}
|
||||
dodo {
|
||||
name = "Dodo"
|
||||
diet = "Seeds"
|
||||
extinct = true
|
||||
taxonomy {
|
||||
species = "Raphus cucullatus"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
So far, you have only amended _properties_.
|
||||
Since you refer to them by name, it makes sense that you "overwrite" the value from the object you're amending.
|
||||
What if you include _elements_ or _entries_ in an amends expression?
|
||||
|
||||
[source,{pkl}]
|
||||
.amendElementsAndEntries.pkl
|
||||
----
|
||||
favoriteFoods {
|
||||
"red berries"
|
||||
"blue berries"
|
||||
["Barn owl"] {
|
||||
"mice"
|
||||
}
|
||||
}
|
||||
|
||||
adultBirdFoods = (favoriteFoods) {
|
||||
[1] = "pebbles" // <1>
|
||||
"worms" // <2>
|
||||
["Falcon"] { // <3>
|
||||
"insects"
|
||||
"amphibians"
|
||||
}
|
||||
["Barn owl"] { // <4>
|
||||
"fish"
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> Explicitly amending _by index_ replaces the element at that index.
|
||||
<2> Without explicit indices, Pkl can't know which element to overwrite, so, instead, it _adds_ an element to the object you're amending.
|
||||
<3> When you write "new" entries (using a key that does not occur in the object you're amending), Pkl also _adds_ them.
|
||||
<4> When you write an entry using a key that exists, this notation amends its value.
|
||||
|
||||
Pkl can't know which of the `favoriteFoods` to overwrite only by their _value_.
|
||||
When you want to _replace_ an element, you have to explicitly amend the element at a specific index.
|
||||
This is why a "plain" element in an amends expression is _added_ to the object being amended.
|
||||
Result:
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
favoriteFoods {
|
||||
["Barn owl"] {
|
||||
"mice"
|
||||
}
|
||||
"red berries"
|
||||
"blue berries"
|
||||
}
|
||||
adultBirdFoods {
|
||||
["Barn owl"] {
|
||||
"mice"
|
||||
"fish"
|
||||
}
|
||||
"red berries"
|
||||
"pebbles"
|
||||
["Falcon"] {
|
||||
"insects"
|
||||
"amphibians"
|
||||
}
|
||||
"worms"
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
=== Modules
|
||||
|
||||
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.
|
||||
|
||||
[source,{pkl}]
|
||||
.pigeon.pkl
|
||||
----
|
||||
name = "Common wood pigeon"
|
||||
diet = "Seeds"
|
||||
taxonomy {
|
||||
species = "Columba palumbus"
|
||||
}
|
||||
----
|
||||
|
||||
You can `import` this module and express `parrot` like you did before.
|
||||
|
||||
[source,{pkl}]
|
||||
.parrot.pkl
|
||||
----
|
||||
import "pigeon.pkl" // <1>
|
||||
|
||||
parrot = (pigeon) {
|
||||
name = "Great green macaw"
|
||||
diet = "Berries"
|
||||
species {
|
||||
species = "Ara ambiguus"
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> Importing `foo.pkl` creates the object `foo`, so you can refer to `pigeon` in this code, like you did before.
|
||||
|
||||
If you run Pkl on both, you will see that it works.
|
||||
Looking at the result, however, you see a (possibly) unexpected difference.
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
$ pkl eval /Users/me/tutorial/pigeon.pkl
|
||||
name = "Common wood pigeon""
|
||||
diet = "Seeds"
|
||||
taxonomy {
|
||||
species = "Columba palumbus"
|
||||
}
|
||||
|
||||
$ pkl eval /Users/me/tutorial/parrot.pkl
|
||||
parrot {
|
||||
name = "Great green macaw"
|
||||
diet = "Berries"
|
||||
taxonomy {
|
||||
species = "Ara ambiguus"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
The object `pigeon` is "spread" in the top-level, while `parrot` is a nested and named object.
|
||||
This is because writing `parrot {...}` defines an object property _in_ the "current" module.
|
||||
|
||||
In order to say that "this module is an object, amended from the `pigeon` module," you use an _amends clause_.
|
||||
|
||||
[source,{pkl}]
|
||||
.parrot.pkl
|
||||
----
|
||||
amends "pigeon.pkl" // <1>
|
||||
|
||||
name = "Great green macaw"
|
||||
----
|
||||
<1> "This" module is the same as `"pigeon.pkl"`, except for what is in the remainder of the file.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
As a first intuition, think of "amending a module" as "filling out a form."
|
||||
====
|
||||
|
||||
== Amending templates
|
||||
|
||||
A Pkl file can be either a _template_ or a _"normal" module_.
|
||||
This terminology describes the _intended use_ of the module and doesn't imply anything about its structure.
|
||||
In other words: just by looking at Pkl code, you can't tell whether it is a template or a "normal" module.
|
||||
|
||||
[source,{pkl}]
|
||||
.acmecicd.pkl
|
||||
----
|
||||
module acmecicd
|
||||
|
||||
class Pipeline {
|
||||
name: String(nameRequiresBranchName)?
|
||||
|
||||
hidden nameRequiresBranchName = (_) ->
|
||||
if (branchName == null)
|
||||
throw("Pipelines that set a 'name' must also set a 'branchName'.")
|
||||
else true
|
||||
|
||||
branchName: String?
|
||||
}
|
||||
|
||||
timeout: Int(this >= 3)
|
||||
|
||||
pipelines: Listing<Pipeline>
|
||||
|
||||
output {
|
||||
renderer = new YamlRenderer {}
|
||||
}
|
||||
----
|
||||
|
||||
Remember that amending is like filling out a form.
|
||||
That's exactly what you're doing here; you're filling out "work order forms".
|
||||
|
||||
Next, add a time-out of one minute for your job.
|
||||
|
||||
[source,{pkl}]
|
||||
.cicd.pkl
|
||||
----
|
||||
amends "acmecicd.pkl"
|
||||
|
||||
timeout = 1
|
||||
----
|
||||
Unfortunately, Pkl does not accept this configuration and provides a rather elaborate error message:
|
||||
[source,plain]
|
||||
----
|
||||
–– Pkl Error –– // <1>
|
||||
Type constraint `this >= 3` violated. // <2>
|
||||
Value: 1 // <3>
|
||||
|
||||
225 | timeout: Int(this >= 3)? // <4>
|
||||
^^^^^^^^^
|
||||
at acmecicd#timeout (file:///Users/me/tutorial/acmecicd.pkl, line 8)
|
||||
|
||||
3 | timeout = 1 // <5>
|
||||
^
|
||||
at cicd#timeout (file:///Users/me/tutorial/cicd.pkl, line 3)
|
||||
|
||||
90 | text = renderer.renderDocument(value) // <6>
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
at pkl.base#Module.output.text (https://github.com/apple/pkl/blob/e4d8c882d/stdlib/base.pkl#L90)
|
||||
|
||||
----
|
||||
<1> Pkl found an error.
|
||||
<2> Which error Pkl found.
|
||||
<3> What the offending value is.
|
||||
<4> Where Pkl found its expectation (line 8 of the amended module).
|
||||
<5> Where Pkl found the offending value (line 3 of the input module).
|
||||
<6> What Pkl evaluated to discover the error.
|
||||
|
||||
When Pkl prints source locations, it also prints clickable links for easy access.
|
||||
For local files, it generates a link for your development environment (https://pkl-lang.org/main/current/pkl-cli/index.html#settings-file[configurable in `+~/.pkl/settings.pkl+`]).
|
||||
For packages imported from elsewhere, if available, Pkl produces `https://` links to their repository.
|
||||
|
||||
Pkl complains about a _type constraint_.
|
||||
Pkl's type system doesn't just protect you from providing a `String` where you expected an `Int`, it even checks which _values_ are allowed.
|
||||
In this case, the minimum time-out is _three_ minutes.
|
||||
If you change the value to `3`, Pkl accepts your configuration.
|
||||
|
||||
[source, shell]
|
||||
----
|
||||
$ pkl eval cicd.pkl
|
||||
timeout: 3
|
||||
pipelines: []
|
||||
----
|
||||
|
||||
You can now define a pipeline.
|
||||
Start off by specifying the name of the pipeline and nothing else.
|
||||
|
||||
[source,{pkl}]
|
||||
.cicd.pkl
|
||||
----
|
||||
amends "acmecicd.pkl"
|
||||
|
||||
timeout = 3
|
||||
pipelines {
|
||||
new { // <1>
|
||||
name = "prb"
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> There is no pipeline object to amend. The `new` keyword gives you an object to amend.
|
||||
|
||||
So far, you've defined objects the same way you amended them.
|
||||
When the name `foo` didn't occur before, `foo { ... }` _creates_ a property called `foo` and assigns to it the object specified on the `...`.
|
||||
If `foo` is an existing object, this notation is an _amend expression_; resulting in a new _object_ (value), but _not_ a new (named) property.
|
||||
Since `pipelines` is a listing, you can _add_ elements by writing expressions in an amend expression.
|
||||
|
||||
In this case, though, there is no object to amend. Writing `myNewPipeline { ... }` defines a _property_, but listings may only include _elements_.
|
||||
This is where you can use the keyword `new`.
|
||||
|
||||
`new` gives you an object to amend.
|
||||
Pkl derives from the context in which `new` is used and what the object to amend should look like.
|
||||
This is called the _default value_ for the context.
|
||||
xref:03_writing_a_template.adoc[The next part] goes into detail about how Pkl does this.
|
||||
|
||||
Running Pkl on your new configuration produces a verbose error.
|
||||
|
||||
[source,plain]
|
||||
.cicd.pkl
|
||||
----
|
||||
–– Pkl Error ––
|
||||
Pipelines that set a 'name' must also set a 'branchName'.
|
||||
|
||||
8 | throw("Pipelines that set a 'name' must also set a 'branchName'.")
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
at acmecicd#Pipeline.nameRequiresBranchName.<function#1> (file:///Users/me/tutorial/acmecicd.pkl, line 8)
|
||||
|
||||
6 | name = "prb"
|
||||
^^^^^
|
||||
at cicd#pipelines[#1].name (file:///Users/me/tutorial/cicd.pkl, line 6)
|
||||
|
||||
90 | text = renderer.renderDocument(value)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
at pkl.base#Module.output.text (https://github.com/apple/pkl/blob/e4d8c882d/stdlib/base.pkl#L90)
|
||||
|
||||
----
|
||||
|
||||
You have hit another type constraint, like `timeout: Int(this >= 3)` before.
|
||||
In this case, the error message consists of an English language sentence, instead of Pkl code.
|
||||
When constraints are complicated or very application specific, template authors can `throw` a more descriptive error message like this.
|
||||
|
||||
The message is quite instructive, so you can fix the error by adding a `branchName`.
|
||||
|
||||
[source,{pkl}]
|
||||
.cicd.pkl
|
||||
----
|
||||
amends "acmecicd.pkl"
|
||||
|
||||
timeout = 3
|
||||
pipelines {
|
||||
new {
|
||||
name = "prb"
|
||||
branchName = "main"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
and indeed
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
$ pkl eval -f yml /Users/me/tutorial/cicd.pkl
|
||||
timeout: 3
|
||||
pipelines:
|
||||
- name: prb
|
||||
branchName: main
|
||||
----
|
||||
441
docs/modules/language-tutorial/pages/03_writing_a_template.adoc
Normal file
441
docs/modules/language-tutorial/pages/03_writing_a_template.adoc
Normal file
@@ -0,0 +1,441 @@
|
||||
= Writing a Template
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
|
||||
In parts xref:01_basic_config.adoc[one] and xref:02_filling_out_a_template.adoc[two], you saw that Pkl provides _validation_ of our configurations.
|
||||
It checks syntax, types and constraints.
|
||||
As you saw in the `acmecicd` example xref:02_filling_out_a_template.adoc#amending-templates[here], the template can provide informative error messages when an amending module violates a type constraint.
|
||||
|
||||
In this final part, you will see some of Pkl's techniques that are particularly relevant for writing a template.
|
||||
|
||||
== Basic types
|
||||
|
||||
Pkl always checks the _syntax_ of its input.
|
||||
As it evaluates your configuration, it also checks _types_.
|
||||
You've seen objects, listings, and mappings already.
|
||||
These provide ways to write structured configuration.
|
||||
Before you can write types for them, you need to know how to write the types for the simplest (unstructured) values.
|
||||
|
||||
These are all Pkl's _basic_ types:
|
||||
|
||||
[source,{pkl}]
|
||||
.pklTutorialPart3.pkl
|
||||
----
|
||||
name: String = "Writing a Template"
|
||||
|
||||
part: Int = 3
|
||||
|
||||
hasExercises: Boolean = true
|
||||
|
||||
amountLearned: Float = 13.37
|
||||
|
||||
duration: Duration = 30.min
|
||||
|
||||
bandwidthRequirementPerSecond: DataSize = 50.mb
|
||||
----
|
||||
|
||||
In the above, you've explicitly annotated the code with type signatures.
|
||||
The default output of Pkl is actually `pcf`, which is a subset of Pkl.
|
||||
Since `pcf` does not have type signatures, running Pkl on this example removes them.
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
$ pkl eval pklTutorialPart3.pkl
|
||||
name = "Writing a Template"
|
||||
part = 3
|
||||
hasExercises = true
|
||||
amountLearned = 13.37
|
||||
duration = 30.min
|
||||
bandwidthRequirementPerSecond = 50.mb
|
||||
----
|
||||
|
||||
Note how `Duration` and `DataSize` help you prevent https://en.wikipedia.org/wiki/Mars_Climate_Orbiter[unit errors] in these common (for configuration) domains.
|
||||
|
||||
== Typed objects, properties and amending
|
||||
|
||||
Having a notation for basic types, you can now write _typed objects_.
|
||||
|
||||
[source,{pkl}]
|
||||
.simpleClass.pkl
|
||||
----
|
||||
class Language { // <1>
|
||||
name: String
|
||||
}
|
||||
|
||||
bestForConfig: Language = new { // <2>
|
||||
name = "Pkl"
|
||||
}
|
||||
----
|
||||
<1> A class definition.
|
||||
<2> A property definition, using the `Language` class.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Although not required (or enforced), it's customary to name properties starting with a lower-case letter. Class names, by that same convention, start with an upper-case letter.
|
||||
====
|
||||
|
||||
You can type objects with _classes_.
|
||||
In this example, you define a class called `Language`.
|
||||
You can now be certain that every instance of `Language` has a property `name` with type `String`.
|
||||
|
||||
Types and values are different things in Pkl.
|
||||
Pkl does not render types in its output,footnote:[Although, some output formats can contain their own form of type annotation. This may be derived from the Pkl type. Type definitions (`class` and `typealias`) themselves are never rendered.] so when you run Pkl on this, you don't see the class _definition_ at all.
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
$ pkl eval simpleClass.pkl
|
||||
bestForConfig {
|
||||
name = "Pkl"
|
||||
}
|
||||
|
||||
----
|
||||
|
||||
Did you notice that the output doesn't just omit the type signature, but also the `= new`?
|
||||
We will discuss this further in the next section.
|
||||
|
||||
When your configuration describes a few different parts like this, you can define one instance and amend it for every other instance.
|
||||
|
||||
For example:
|
||||
|
||||
[source,{pkl}]
|
||||
.pklTutorialParts.pkl
|
||||
----
|
||||
class TutorialPart {
|
||||
name: String
|
||||
|
||||
part: Int
|
||||
|
||||
hasExercises: Boolean
|
||||
|
||||
amountLearned: Float
|
||||
|
||||
duration: Duration
|
||||
|
||||
bandwidthRequirementPerSecond: DataSize
|
||||
}
|
||||
|
||||
pklTutorialPart1: TutorialPart = new {
|
||||
name = "Basic Configuration"
|
||||
part = 1
|
||||
hasExercises = true
|
||||
amountLearned = 13.37
|
||||
duration = 30.min
|
||||
bandwidthRequirementPerSecond = 50.mib.toUnit("mb")
|
||||
}
|
||||
|
||||
pklTutorialPart2: TutorialPart = (pklTutorialPart1) {
|
||||
name = "Filling out a Template"
|
||||
part = 2
|
||||
}
|
||||
|
||||
pklTutorialPart3: TutorialPart = (pklTutorialPart1) {
|
||||
name = "Writing a Template"
|
||||
part = 3
|
||||
}
|
||||
|
||||
----
|
||||
|
||||
You can read this as saying "``pklTutorialPart2`` & `pklTutorialPart3` are exactly like `pklTutorialPart1`, except for their `name` and `part`."
|
||||
Running Pkl confirms this:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
$ pkl eval pklTutorialParts.pkl
|
||||
pklTutorialPart1 {
|
||||
name = "Basic Configuration"
|
||||
part = 1
|
||||
hasExercises = true
|
||||
amountLearned = 13.37
|
||||
duration = 30.min
|
||||
bandwidthRequirementPerSecond = 50.mb
|
||||
}
|
||||
pklTutorialPart2 {
|
||||
name = "Filling out a Template"
|
||||
part = 2
|
||||
hasExercises = true
|
||||
amountLearned = 13.37
|
||||
duration = 30.min
|
||||
bandwidthRequirementPerSecond = 50.mb
|
||||
}
|
||||
pklTutorialPart3 {
|
||||
name = "Writing a Template"
|
||||
part = 3
|
||||
hasExercises = true
|
||||
amountLearned = 13.37
|
||||
duration = 30.min
|
||||
bandwidthRequirementPerSecond = 50.mb
|
||||
}
|
||||
|
||||
----
|
||||
|
||||
Sadly, `pklTutorialParts.pkl` is a _rewrite_ of `pklTutorial.pkl`.
|
||||
It creates a separate `class TutorialPart` and instantiates three properties with it (`pklTutorialPart1`, `pklTutorialPart2` and `pklTutorialPart3`).
|
||||
In doing so, it implicitly moves everything "down" one level (`pklTutorialPart3` is now a property in the module `pklTutorialParts`, whereas above, in `pklTutorialPart3.pkl` it was its own module).
|
||||
This is not very DRY.
|
||||
As a matter of fact, you don't need this rewrite.
|
||||
|
||||
Any `.pkl` file defines a _module_ in Pkl.
|
||||
Any module is represented by a _module class_, which is an actual Pkl `class`.
|
||||
A module is not quite the same as any other class, because Pkl never renders class definitions on the output.
|
||||
However, when you ran Pkl on `pklTutorialPart3.pkl`, it _did_ produce an output.
|
||||
This is because a module also defines an _instance_ of the module class.
|
||||
|
||||
The values given to properties in a module (or in any "normal" class) are called _default values_.
|
||||
When you instantiate a class, all the properties for which you _don't_ provide a value are populated from the class' default values.
|
||||
|
||||
In our examples of tutorial parts, only the `name` and `part` varied across instances.
|
||||
You can express this by adding default values to the (module) class definition.
|
||||
Instead of starting from a particular tutorial part, you can define the module `tutorialPart` as follows:
|
||||
|
||||
[source,{pkl}]
|
||||
.TutorialPart.pkl
|
||||
----
|
||||
name: String // <1>
|
||||
|
||||
part: Int // <1>
|
||||
|
||||
hasExercises: Boolean = true // <2>
|
||||
|
||||
amountLearned: Float = 13.37 // <2>
|
||||
|
||||
duration: Duration = 30.min // <2>
|
||||
|
||||
bandwidthRequirementPerSecond: DataSize = 50.mb // <2>
|
||||
----
|
||||
<1> No default value given.
|
||||
<2> Default value given.
|
||||
|
||||
Running this through Pkl gives an error, or course, because of the missing values:
|
||||
|
||||
[source, shell]
|
||||
----
|
||||
$ pkl eval TutorialPart.pkl
|
||||
–– Pkl Error ––
|
||||
Tried to read property `name` but its value is undefined.
|
||||
|
||||
1 | name: String
|
||||
^^^^
|
||||
...
|
||||
----
|
||||
|
||||
An individual part now only has to fill in the missing fields, so you can change `pklTutorialPart3.pkl` to amend this:
|
||||
|
||||
[source,{pkl}]
|
||||
.pklTutorialPart3.pkl
|
||||
----
|
||||
amends "TutorialPart.pkl"
|
||||
|
||||
name = "Writing a Template"
|
||||
|
||||
part = 3
|
||||
----
|
||||
|
||||
This results in
|
||||
|
||||
[source, shell]
|
||||
----
|
||||
$ pkl eval pklTutorialPart3.pkl
|
||||
name = "Writing a Template"
|
||||
part = 3
|
||||
hasExercises = true
|
||||
amountLearned = 13.37
|
||||
duration = 30.min
|
||||
bandwidthRequirementPerSecond = 50.mb
|
||||
|
||||
----
|
||||
|
||||
This now behaves exactly like our `pklTutorialPart3: TutorialPart = (pklTutorialPart1) {...` before.
|
||||
`pklTutorialPart3` is now defined as the value we get by amending `tutorialPart` and giving it a `name` and a `part`.
|
||||
|
||||
[IMPORTANT]
|
||||
====
|
||||
Amending anything _never changes its type_.
|
||||
When we amend an object of type `Foo`, the result will always be precisely of type `Foo`.
|
||||
By "precisely" we mean, that amending an object also can't "turn it into" an instance of a sub-class of the class of the object being amended.
|
||||
====
|
||||
|
||||
== A new template
|
||||
|
||||
Now that you know about types, you can start writing your first template.
|
||||
So far, you've written configurations with Pkl, either without a template, or using a template on Pkl Hub.
|
||||
It is often easiest to first write a (typical) configuration for which you want to create a template.
|
||||
Suppose you want to define what a live workshop for this tutorial looks like.
|
||||
Consider this example:
|
||||
|
||||
[source,{pkl}]
|
||||
.workshop2023.pkl
|
||||
----
|
||||
title = "Pkl: Configure your Systems in New Ways"
|
||||
interactive = true
|
||||
seats = 100
|
||||
occupancy = 0.85
|
||||
duration = 1.5.h
|
||||
`abstract` = """
|
||||
With more systems to configure, the software industry is drowning in repetitive and brittle configuration files.
|
||||
YAML and other configuration formats have been turned into programming languages against their will.
|
||||
Unsurprisingly, they don’t live up to the task.
|
||||
Pkl puts you back in control.
|
||||
"""
|
||||
|
||||
event {
|
||||
name = "Migrating Birds between hemispheres"
|
||||
year = 2023
|
||||
}
|
||||
|
||||
instructors {
|
||||
"Kate Sparrow"
|
||||
"Jerome Owl"
|
||||
}
|
||||
|
||||
sessions {
|
||||
new {
|
||||
date = "8/14/2023"
|
||||
time = 30.min
|
||||
}
|
||||
new {
|
||||
date = "8/15/2023"
|
||||
time = 30.min
|
||||
}
|
||||
}
|
||||
|
||||
assistants {
|
||||
["kevin"] = "Kevin Parrot"
|
||||
["betty"] = "Betty Harrier"
|
||||
}
|
||||
|
||||
agenda {
|
||||
["beginners"] {
|
||||
title = "Basic Configuration"
|
||||
part = 1
|
||||
duration = 45.min
|
||||
}
|
||||
["intermediates"] {
|
||||
title = "Filling out a Template"
|
||||
part = 2
|
||||
duration = 45.min
|
||||
}
|
||||
["experts"] {
|
||||
title = "Writing a Template"
|
||||
part = 3
|
||||
duration = 45.min
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Call your new template `Workshop.pkl`.
|
||||
Although not required, it's good practice to always name your template with a `module`-clause.
|
||||
Defining the first few properties are like you saw in the previous section:
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
module Workshop
|
||||
|
||||
title: String
|
||||
|
||||
interactive: Boolean
|
||||
|
||||
seats: Int
|
||||
|
||||
occupancy: Float
|
||||
|
||||
duration: Duration
|
||||
|
||||
`abstract`: String
|
||||
----
|
||||
|
||||
Unlike these first few properties, `event` is an object with multiple properties.
|
||||
To be able to type `event`, you need a `class`.
|
||||
You've seen before how to define this:
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
class Event {
|
||||
name: String
|
||||
|
||||
year: Int
|
||||
}
|
||||
|
||||
event: Event
|
||||
----
|
||||
|
||||
Next, `instructors` isn't an object with properties, but a list of unnamed values.
|
||||
Pkl offers the `Listing` type for this:
|
||||
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
instructors: Listing<String>
|
||||
----
|
||||
|
||||
`sessions` is a `Listing` of objects, so you need a `Session` class.
|
||||
[source,{pkl}]
|
||||
----
|
||||
class Session {
|
||||
time: Duration
|
||||
|
||||
date: String
|
||||
}
|
||||
|
||||
sessions: Listing<Session>
|
||||
----
|
||||
|
||||
`assistants` has a structure like an object, in that all the values are named, but the set of names is not fixed for all possible workshops (and some workshops may have more assistants than others). The Pkl type for this is a `Mapping`:
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
assistants: Mapping<String, String>
|
||||
----
|
||||
|
||||
Finally, for every workshop session, there is an `agenda`, which describes which ``TutorialPart``s are covered.
|
||||
You already defined `TutorialPart.pkl` as its own module, so you should not define a separate class, but rather `import` that module and reuse it here:
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
import "TutorialPart.pkl" // <1>
|
||||
|
||||
agenda: Mapping<String, TutorialPart>
|
||||
----
|
||||
<1> This `import` clause brings the name `TutorialPart` into scope, which is the module class as discussed above. Note that import clauses must appear before property definitions.
|
||||
|
||||
Putting it all together, your `Workshop.pkl` template looks like this:
|
||||
|
||||
[source,{pkl}]
|
||||
.Workshop.pkl
|
||||
----
|
||||
module Workshop
|
||||
|
||||
import "TutorialPart.pkl"
|
||||
|
||||
title: String
|
||||
|
||||
interactive: Boolean
|
||||
|
||||
seats: Int
|
||||
|
||||
occupancy: Float
|
||||
|
||||
duration: Duration
|
||||
|
||||
`abstract`: String
|
||||
|
||||
class Event {
|
||||
name: String
|
||||
|
||||
year: Int
|
||||
}
|
||||
|
||||
event: Event
|
||||
|
||||
instructors: Listing<String>
|
||||
|
||||
class Session {
|
||||
time: Duration
|
||||
|
||||
date: String
|
||||
}
|
||||
|
||||
sessions: Listing<Session>
|
||||
|
||||
assistants: Mapping<String, String>
|
||||
|
||||
agenda: Mapping<String, TutorialPart>
|
||||
----
|
||||
17
docs/modules/language-tutorial/pages/index.adoc
Normal file
17
docs/modules/language-tutorial/pages/index.adoc
Normal file
@@ -0,0 +1,17 @@
|
||||
= Tutorial
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
|
||||
Welcome to the Pkl tutorial. We will get you up and running quickly!
|
||||
If you are new to Pkl, we recommend that you follow along with the code examples.
|
||||
This tutorial describes interactions with the xref:pkl-cli:index.adoc#repl[REPL].
|
||||
For an even more interactive experience, follow along using a xref:main:ROOT:tools.adoc[supported editor].
|
||||
|
||||
For more comprehensive documentation, see xref:language-reference:index.adoc[Language Reference].
|
||||
For ready-to-go examples with full source code, see xref:ROOT:examples.adoc[].
|
||||
For API documentation, see xref:ROOT:standard-library.adoc[Standard Library].
|
||||
|
||||
Pick a tutorial by topic:
|
||||
|
||||
1. xref:01_basic_config.adoc[Basic Configuration]
|
||||
2. xref:02_filling_out_a_template.adoc[Filling out a Template]
|
||||
3. xref:03_writing_a_template.adoc[Writing a Template]
|
||||
782
docs/modules/pkl-cli/pages/index.adoc
Normal file
782
docs/modules/pkl-cli/pages/index.adoc
Normal file
@@ -0,0 +1,782 @@
|
||||
= CLI
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-homebrew: https://brew.sh
|
||||
:uri-pkl-macos-download: {github-releases}/pkl-cli-macos-{pkl-artifact-version}.bin
|
||||
:uri-pkl-linux-amd64-download: {github-releases}/pkl-cli-linux-amd64-{pkl-artifact-version}.bin
|
||||
:uri-pkl-linux-aarch64-download: {github-releases}/pkl-cli-linux-aarch64-{pkl-artifact-version}.bin
|
||||
:uri-pkl-alpine-download: {github-releases}/pkl-cli-alpine-amd64-{pkl-artifact-version}.bin
|
||||
:uri-pkl-java-download: {github-releases}/pkl-cli-java-{pkl-artifact-version}.jar
|
||||
:uri-pkl-stdlib-docs-settings: {uri-pkl-stdlib-docs}/settings/
|
||||
:uri-pkl-cli-main-sources: {uri-github-tree}/pkl-cli/src/main/kotlin/org/pkl/cli
|
||||
:uri-pkl-cli-CliEvaluatorOptions: {uri-pkl-cli-main-sources}/CliEvaluatorOptions.kt
|
||||
:uri-certificates: {uri-github-tree}/pkl-commons-cli/src/main/resources/org/pkl/commons/cli/commands
|
||||
|
||||
The `pkl` command-line interface (CLI) evaluates Pkl modules and writes their output to the console or a file.
|
||||
For interactive development, the CLI includes a Read-Eval-Print Loop (REPL).
|
||||
|
||||
[[installation]]
|
||||
== Installation
|
||||
|
||||
The CLI comes in multiple flavors:
|
||||
|
||||
* Native macOS executable for amd64 (tested on macOS 10.15)
|
||||
* Native Linux executable for amd64 (tested on Oracle Linux 8)
|
||||
* Native Linux executable for aarch64 (tested on Oracle Linux 8)
|
||||
* Native Alpine Linux executable for amd64 (cross-compiled and tested on Oracle Linux 8)
|
||||
* Java executable (tested with Java 8/11/14 on macOS and Oracle Linux)
|
||||
|
||||
On macOS and Linux, we recommend using the native executables.
|
||||
They are self-contained, start up instantly, and run complex Pkl code much faster than the Java executable.
|
||||
|
||||
.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 8 (or higher) runtime on the system path, has a noticeable startup delay,
|
||||
and runs complex Pkl code slower than the native executables.
|
||||
|
||||
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.
|
||||
|
||||
//TODO uncomment this after brew formula is merged and available
|
||||
// [[homebrew]]
|
||||
// === Homebrew
|
||||
//
|
||||
// Release versions can be installed with {uri-homebrew}[Homebrew].
|
||||
//
|
||||
// ifdef::is-release-version[]
|
||||
// To install Pkl, run:
|
||||
//
|
||||
// [source,shell]
|
||||
// ----
|
||||
// brew install pkl
|
||||
// ----
|
||||
//
|
||||
// To update Pkl, run:
|
||||
//
|
||||
// [source,shell]
|
||||
// ----
|
||||
// brew update
|
||||
// brew upgrade pkl # or just `brew upgrade`
|
||||
// ----
|
||||
// endif::[]
|
||||
//
|
||||
// ifndef::is-release-version[]
|
||||
// For instructions, switch to a release version of this page.
|
||||
// endif::[]
|
||||
|
||||
[[download]]
|
||||
=== Download
|
||||
|
||||
Development and release versions can be downloaded and installed manually.
|
||||
|
||||
=== macOS Executable
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
curl -o pkl {uri-pkl-macos-download}
|
||||
chmod +x pkl
|
||||
./pkl --version
|
||||
----
|
||||
|
||||
This should print something similar to:
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
Pkl {pkl-version} (macOS, native)
|
||||
----
|
||||
|
||||
[[linux-executable]]
|
||||
=== Linux Executable
|
||||
|
||||
The Linux executable is dynamically linked against _glibc_ and _libstdc{plus}{plus}_ for the amd64 and aarch64 architectures.
|
||||
For a statically linked executable, see <<Alpine Linux Executable>>.
|
||||
|
||||
On amd64:
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
# on amd64
|
||||
curl -o pkl {uri-pkl-linux-amd64-download}
|
||||
chmod +x pkl
|
||||
./pkl --version
|
||||
----
|
||||
|
||||
On aarch64:
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
curl -o pkl {uri-pkl-linux-aarch64-download}
|
||||
chmod +x pkl
|
||||
./pkl --version
|
||||
----
|
||||
|
||||
This should print something similar to:
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
Pkl {pkl-version} (Linux, native)
|
||||
----
|
||||
|
||||
[[alpine-linux-executable]]
|
||||
=== Alpine Linux Executable
|
||||
|
||||
The Alpine Linux executable is statically linked against _musl libc_ and _libstdc{plus}{plus}_.
|
||||
For a dynamically linked executable, see <<Linux Executable>>.
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
curl -o pkl {uri-pkl-alpine-download}
|
||||
chmod +x pkl
|
||||
./pkl --version
|
||||
----
|
||||
|
||||
This should print something similar to:
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
Pkl {pkl-version} (Linux, native)
|
||||
----
|
||||
|
||||
NOTE: We currently do not support the aarch64 architecture for Alpine Linux.
|
||||
|
||||
=== Java Executable
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
curl -o jpkl {uri-pkl-java-download}
|
||||
chmod +x jpkl
|
||||
./jpkl --version
|
||||
----
|
||||
|
||||
This should print something similar to:
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
Pkl {pkl-version} (macOS 10.16, Java 11.0.9)
|
||||
----
|
||||
|
||||
[[usage]]
|
||||
== Usage
|
||||
|
||||
*Synopsis:* `pkl <subcommand> [<options>] [<args>]`
|
||||
|
||||
For a brief description of available options, run `pkl -h`.
|
||||
|
||||
NOTE: The Java executable is named `jpkl`.
|
||||
|
||||
[[command-eval]]
|
||||
=== `pkl eval`
|
||||
|
||||
*Synopsis:* `pkl eval [<options>] [<modules>]`
|
||||
|
||||
Evaluate the given Pkl `<modules>` and produce their rendering results.
|
||||
|
||||
<modules>::
|
||||
The absolute or relative URIs of the modules to evaluate.
|
||||
Relative URIs are resolved against the working directory.
|
||||
|
||||
==== Options
|
||||
|
||||
[[format]]
|
||||
.-f, --format
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: `yaml` +
|
||||
The output format to generate.
|
||||
The default output renderer for a module supports the following formats:
|
||||
|
||||
* `json`
|
||||
* `jsonnet`
|
||||
* `pcf`
|
||||
* `plist`
|
||||
* `properties`
|
||||
* `textproto`
|
||||
* `xml`
|
||||
* `yaml`
|
||||
|
||||
If no format is set, the default renderer chooses `pcf`.
|
||||
====
|
||||
|
||||
[[output-path]]
|
||||
.-o, --output-path
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: "config.yaml" +
|
||||
The file path where the output file is placed.
|
||||
Relative paths are resolved against the project directory.
|
||||
|
||||
// suppress inspection "AsciiDocLinkResolve"
|
||||
This option is mutually exclusive with link:#multiple-file-output-path[`--multiple-file-output-path`].
|
||||
If neither option is set, each module's `output.text` is written to standard output.
|
||||
|
||||
If multiple source modules are given, placeholders can be used to map them to different output files.
|
||||
The following placeholders are supported:
|
||||
|
||||
`%\{moduleDir}`:::
|
||||
The directory path of the module, relative to the working directory.
|
||||
Only available when evaluating file-based modules.
|
||||
|
||||
`%\{moduleName}`:::
|
||||
The simple module name as inferred from the module URI.
|
||||
For hierarchical URIs such as `+file:///foo/bar/baz.pkl+`, this is the last path segment without file extension.
|
||||
|
||||
`%\{outputFormat}`:::
|
||||
The requested output format.
|
||||
Only available if `--format` is set.
|
||||
|
||||
If multiple source modules are mapped to the same output file, their outputs are concatenated.
|
||||
By default, module outputs are separated with `---`, as in a YAML stream.
|
||||
// suppress inspection "AsciiDocLinkResolve"
|
||||
The separator can be customized using the link:#module-output-separator[`--module-output-separator`] option.
|
||||
====
|
||||
|
||||
[[module-output-separator]]
|
||||
.--module-output-separator
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `---` (as in a YAML stream) +
|
||||
The separator to use when multiple module outputs are written to the same file, or to standard output.
|
||||
====
|
||||
|
||||
[[multiple-file-output-path]]
|
||||
.-m, --multiple-file-output-path
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: "output/" +
|
||||
The directory where a module's output files are placed.
|
||||
|
||||
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 `--multiple-file-output-path`,
|
||||
and a value determines the file's contents.
|
||||
|
||||
// suppress inspection "AsciiDocLinkResolve"
|
||||
This option cannot be used together with any of the following:
|
||||
|
||||
* xref:output-path[`--output-path`]
|
||||
* xref:expression[`--expression`]
|
||||
|
||||
// suppress inspection "AsciiDocLinkResolve"
|
||||
This option supports the same placeholders as link:#output-path[`--output-path`].
|
||||
|
||||
Examples:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
# Write files to `output/`
|
||||
pkl eval -m output/ myFiles.pkl
|
||||
|
||||
# Write files to the current working directory
|
||||
pkl eval -m . myFiles.pkl
|
||||
|
||||
# Write foo.pkl's files to the `foo` directory, and bar.pkl's files
|
||||
# to the `bar` directory
|
||||
pkl eval -m "%{moduleName}" foo.pkl bar.pkl
|
||||
----
|
||||
|
||||
For additional details, see xref:language-reference:index.adoc#multiple-file-output[Multiple File Output]
|
||||
in the language reference.
|
||||
====
|
||||
|
||||
[[expression]]
|
||||
.-x, --expression
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
The expression to be evaluated within the module.
|
||||
|
||||
This option causes Pkl to evaluate the provided expression instead of the module's `output.text` or `output.files` properties.
|
||||
The resulting value is then stringified, and written to either standard out, or the designated output file.
|
||||
|
||||
For example, consider the following Pkl module:
|
||||
|
||||
.pigeon.pkl
|
||||
[source%tested,{pkl}]
|
||||
----
|
||||
metadata {
|
||||
species = "Pigeon"
|
||||
}
|
||||
----
|
||||
|
||||
The following command prints `Pigeon` to the console:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
pkl -x metadata.name pigeon.pkl
|
||||
# => Pigeon
|
||||
----
|
||||
|
||||
Setting an `--expression` flag can be thought of as substituting the expression in place of a module's `output.text` property.
|
||||
Running the previous command is conceptually the same as if the below module were evaluated without the `--expression` flag:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
metadata {
|
||||
species = "Pigeon"
|
||||
}
|
||||
|
||||
output {
|
||||
text = metadata.name.toString()
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
This command also takes <<common-options, common options>>.
|
||||
|
||||
[[command-server]]
|
||||
=== `pkl server`
|
||||
|
||||
*Synopsys:* `pkl server`
|
||||
|
||||
Run as a server that communicates over standard input/output.
|
||||
|
||||
This option is used for embedding Pkl in an external client, such as xref:swift:ROOT:index.adoc[pkl-swift] or xref:go:ROOT:index.adoc[pkl-go].
|
||||
|
||||
[[command-test]]
|
||||
=== `pkl test`
|
||||
|
||||
*Synopsys:* `pkl test [<options>] [<modules>]`
|
||||
|
||||
Evaluate the given `<modules>` as _tests_, producing a test report and appropriate exit code.
|
||||
|
||||
Renderers defined in test files will be ignored by the `test` command.
|
||||
|
||||
<modules>::
|
||||
The absolute or relative URIs of the modules to test. Relative URIs are resolved against the working directory.
|
||||
|
||||
==== Options
|
||||
|
||||
[[junit-reports]]
|
||||
.--junit-reports
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: `./build/test-results` +
|
||||
Directory where to store JUnit reports.
|
||||
|
||||
No JUnit reports will be generated if this option is not present.
|
||||
====
|
||||
|
||||
[[overwrite]]
|
||||
.--overwrite
|
||||
[%collapsible]
|
||||
====
|
||||
Force generation of expected examples. +
|
||||
The old expected files will be deleted if present.
|
||||
====
|
||||
|
||||
This command also takes <<common-options, common options>>.
|
||||
|
||||
[[command-repl]]
|
||||
=== `pkl repl`
|
||||
|
||||
*Synopsys:* `pkl repl [<options>]`
|
||||
|
||||
Start a REPL session.
|
||||
|
||||
This command takes <<common-options, common options>>.
|
||||
|
||||
[[command-project-package]]
|
||||
=== `pkl project package`
|
||||
|
||||
*Synopsis:* `pkl project package <project-dir>`
|
||||
|
||||
This command prepares a project to be published as a package.
|
||||
Given a project directory, it creates the following artifacts:
|
||||
|
||||
* `<name>@<version>` - the package metadata file
|
||||
* `<name>@<version>.sha256` - the dependency metadata file's SHA-256 checksum
|
||||
* `<name>@<version>.zip` - the package archive
|
||||
* `<name>@<version>.zip.sha256` - the package archive's SHA-256 checksum
|
||||
|
||||
These artifacts are expected to be published to an HTTPS server, such that the metadata and zip files can be fetched at their expected locations.
|
||||
|
||||
The package ZIP should be available at the `packageZipUrl` location specified in the `PklProject` file
|
||||
The package metadata should be available at the package URI's derived HTTPS URL.
|
||||
For example, given package `package://example.com/mypackage@1.0.0`, the metadata file should be published to `+https://example.com/mypackage@1.0.0+`.
|
||||
|
||||
During packaging, this command runs these additional steps:
|
||||
|
||||
1. Run the package's API tests, if any are defined.
|
||||
2. Validates that if the package has already been published, that the package's metadata is identical. This step can be skipped using the `--skip-publish-check` flag.
|
||||
|
||||
Examples:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
# Search the current working directory for a project, and package it.
|
||||
pkl project package
|
||||
|
||||
# Package all projects within the `packages/` directory to `.out`, writing each package's artifacts to its own directory.
|
||||
pkl project package --output-path ".out/%{name}@%{version}/" packages/*/
|
||||
----
|
||||
|
||||
==== Options
|
||||
|
||||
.--output-path
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `.out`
|
||||
|
||||
The directory to write artifacts to.
|
||||
Accepts the following placeholders:
|
||||
|
||||
`%\{name}`:: The name of the package
|
||||
`%\{version}`:: The version of the package
|
||||
====
|
||||
|
||||
.--skip-publish-check
|
||||
[%collapsible]
|
||||
====
|
||||
Skips checking whether a package has already been published with different contents.
|
||||
|
||||
By default, the packager will check whether a package at the same version has already been published.
|
||||
If the package has been published, it validates that the package's metadata is identical to the locally generated metadata.
|
||||
====
|
||||
|
||||
.--junit-reports
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: `./build/test-results` +
|
||||
Directory where to store JUnit reports.
|
||||
|
||||
No JUnit reports will be generated if this option is not present.
|
||||
====
|
||||
|
||||
.--overwrite
|
||||
[%collapsible]
|
||||
====
|
||||
Force generation of expected examples. +
|
||||
The old expected files will be deleted if present.
|
||||
====
|
||||
|
||||
This command also takes <<common-options,common options>>.
|
||||
|
||||
[[command-project-resolve]]
|
||||
=== `pkl project resolve`
|
||||
|
||||
*Synopsis:* `pkl project resolve <project-dir>`
|
||||
|
||||
This command takes the dependencies of a project, and writes the resolved versions a file at path `PklProject.deps.json`.
|
||||
|
||||
It builds a dependency list, taking the latest minor version in case of version conflicts.
|
||||
For more details, see the xref:language-reference:index.adoc#resolving-dependencies[resolving dependencies] section of the language reference.
|
||||
|
||||
Examples:
|
||||
[source,shell]
|
||||
----
|
||||
# Search the current working directory for a project, and resolve its dependencies.
|
||||
pkl project resolve
|
||||
|
||||
# Resolve dependencies for all projects within the `packages/` directory.
|
||||
pkl project resolve packages/*/
|
||||
----
|
||||
|
||||
==== Options
|
||||
|
||||
This command accepts <<common-options,common options>>.
|
||||
|
||||
[[command-download-package]]
|
||||
=== `pkl download-package`
|
||||
|
||||
*Synopsis*: `pkl download-package <package-uri>`
|
||||
|
||||
This command downloads the specified packages to the cache directory.
|
||||
If the
|
||||
package already exists in the cache directory, this command is a no-op.
|
||||
|
||||
==== Options
|
||||
|
||||
This command accepts <<common-options,common options>>.
|
||||
|
||||
[[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:
|
||||
|
||||
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:
|
||||
|
||||
include::../../pkl-cli/partials/cli-project-options.adoc[]
|
||||
|
||||
== Evaluating Modules
|
||||
|
||||
Say we have the following module:
|
||||
|
||||
[[config.pkl]]
|
||||
.config.pkl
|
||||
[source,{pkl}]
|
||||
----
|
||||
bird {
|
||||
species = "Pigeon"
|
||||
diet = "Seeds"
|
||||
}
|
||||
parrot = (bird) {
|
||||
species = "Parrot"
|
||||
diet = "Berries"
|
||||
}
|
||||
----
|
||||
|
||||
To evaluate this module and write its output to standard output, run:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
pkl eval config.pkl
|
||||
----
|
||||
|
||||
You should see the following output:
|
||||
|
||||
[source,{pkl}]
|
||||
----
|
||||
bird {
|
||||
species = "Pigeon"
|
||||
diet = "Seeds"
|
||||
}
|
||||
parrot {
|
||||
species = "Parrot"
|
||||
diet = "Berries"
|
||||
}
|
||||
----
|
||||
|
||||
To render output as JSON, YAML, XML property list, or Java properties,
|
||||
use `--format json`, `--format yaml`, `--format plist`, or `--format properties`, respectively.
|
||||
|
||||
To control the output format from within Pkl code, see xref:language-reference:index.adoc#module-output[Module Output].
|
||||
|
||||
To read a source module from standard input rather than a file, use `-` as a module name:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
echo mod2.pkl | pkl eval mod1.pkl - mod3.pkl
|
||||
----
|
||||
|
||||
This is especially useful in environments that don't support `/dev/stdin`.
|
||||
|
||||
To write output to a file rather than standard output, use `--output-path some/file.ext`.
|
||||
|
||||
[[batch-evaluation]]
|
||||
=== Batch Evaluation
|
||||
|
||||
Multiple modules can be evaluated at once:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
pkl eval config1.pkl config2.pkl config3.pkl
|
||||
----
|
||||
|
||||
To write module outputs to separate output files, `--output-path` supports the following placeholders:
|
||||
|
||||
`%\{moduleDir}`:: the directory path of the source module, relative to the working directory (only available for file based modules)
|
||||
`%\{moduleName}`:: the last path segment of the module URI, without file extension
|
||||
`%\{outputFormat}`:: the target format (only available if `--format` is set)
|
||||
|
||||
The following run produces three JSON files placed next to the given source modules:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
pkl eval --format=json --output-path=%{moduleDir}/%{moduleName}.json config1.pkl config2.pkl config3.pkl
|
||||
----
|
||||
|
||||
If multiple module outputs are written to the same file, or to standard output, their outputs are concatenated.
|
||||
By default, module outputs are separated with `---`, as in a YAML stream.
|
||||
The separator can be customized using the `--module-output-separator` option.
|
||||
|
||||
[[repl]]
|
||||
== Working with the REPL
|
||||
|
||||
To start a REPL session, run `pkl repl`:
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes"]
|
||||
----
|
||||
$ pkl repl
|
||||
Welcome to Pkl {pkl-version}.
|
||||
Type an expression to have it evaluated.
|
||||
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:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
pkl> :load config.pkl
|
||||
----
|
||||
|
||||
To evaluate the `bird.name` property, run:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
pkl> bird.name
|
||||
"Pigeon"
|
||||
----
|
||||
|
||||
To evaluate the entire module, force-evaluate `this`:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
pkl> :force this
|
||||
----
|
||||
|
||||
=== REPL Commands
|
||||
|
||||
Commands start with `:` and can be tab-completed:
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes,+macros"]
|
||||
----
|
||||
pkl> :{empty}kbd:[Tab]
|
||||
clear examples force help load quit reset
|
||||
pkl> :q{empty}kbd:[Tab]
|
||||
pkl> :quit{empty}kbd:[Return]
|
||||
$
|
||||
----
|
||||
|
||||
Commands can be abbreviated with any unique name prefix:
|
||||
|
||||
[source,shell]
|
||||
[subs="+attributes,+macros"]
|
||||
----
|
||||
pkl> :q{empty}kbd:[Return]
|
||||
$
|
||||
----
|
||||
|
||||
To learn more about each command, run the `:help` command.
|
||||
|
||||
Some commands support further command-specific tab completion.
|
||||
For example, the `:load` command supports completing file paths.
|
||||
|
||||
With commands out of the way, let's move on to evaluating code.
|
||||
|
||||
=== Evaluating Code
|
||||
|
||||
To evaluate an expression, type the expression and hit kbd:[Return].
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
pkl> 2 + 4
|
||||
6
|
||||
----
|
||||
|
||||
Apart from expressions, the REPL also accepts property, function, and class definitions.
|
||||
(See the xref:language-reference:index.adoc[Language Reference] to learn more about these language concepts.)
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
pkl> hello = "Hello, World!"
|
||||
pkl> hello
|
||||
"Hello, World!"
|
||||
pkl> function double(n) = 2 * n
|
||||
pkl> double(5)
|
||||
10
|
||||
pkl> class Bird { name: String }
|
||||
pkl> new Bird { species = "Pigeon" }
|
||||
{
|
||||
name = ?
|
||||
}
|
||||
----
|
||||
|
||||
Top-level expressions are only supported in the REPL.
|
||||
In a regular module, every expression is contained in a definition, and only definitions exist at the top level.
|
||||
|
||||
=== Redefining Members
|
||||
|
||||
Existing members can be redefined:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
pkl> species = "Pigeon"
|
||||
pkl> species
|
||||
"Pigeon"
|
||||
pkl> species = "Barn"
|
||||
pkl> species
|
||||
"Barn"
|
||||
pkl> species += " Owl"
|
||||
pkl> species
|
||||
"Barn owl"
|
||||
----
|
||||
|
||||
Due to Pkl's late binding semantics, redefining a member affects dependent members:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
pkl> name = "Barn"
|
||||
pkl> species = "$name Owl"
|
||||
pkl> species
|
||||
"Barn owl"
|
||||
pkl> name = "Elf"
|
||||
pkl> species
|
||||
"Elf Owl"
|
||||
----
|
||||
|
||||
Redefining members is only supported in the REPL. Under the hood,
|
||||
it works as follows:
|
||||
|
||||
* The REPL environment is represented as a synthetic Pkl module.
|
||||
* When a new member is defined, it is added to the current REPL module.
|
||||
* When an existing member is redefined, it is added to a new REPL module that xref:language-reference:index.adoc#module-amend[amends] the previous REPL module.
|
||||
|
||||
[[settings-file]]
|
||||
== Settings File
|
||||
|
||||
The Pkl settings file allows to customize the CLI experience.
|
||||
|
||||
A settings file is a Pkl module amending the `pkl.settings` standard library module.
|
||||
Its default location is `~/.pkl/settings.pkl`.
|
||||
To use a different settings file, set the `--settings` command line option, for example `--settings mysettings.pkl`.
|
||||
To enforce default settings, use `--settings pkl:settings`.
|
||||
The settings file is also honored by (and configurable through) the Gradle plugin and `CliEvaluator` API.
|
||||
|
||||
Here is a typical settings file:
|
||||
|
||||
.~/.pkl/settings.pkl
|
||||
[source%parsed,{pkl}]
|
||||
----
|
||||
amends "pkl:settings" // <1>
|
||||
|
||||
editor = Idea // <2>
|
||||
----
|
||||
<1> A settings file should amend the `pkl.settings` standard library module.
|
||||
<2> Configures IntelliJ IDEA as the preferred editor.
|
||||
Other supported values are `System`, `GoLand`, `TextMate`, `Sublime`, `Atom`, and `VsCode`.
|
||||
|
||||
With the above settings file in place, kbd:[Cmd]+Double-clicking a source code link in a stack trace opens the corresponding file in IntelliJ IDEA at the correct location.
|
||||
|
||||
To learn more about available settings, see link:{uri-pkl-stdlib-docs-settings}[pkl.settings].
|
||||
|
||||
[[ca-certs]]
|
||||
== CA Certificates
|
||||
|
||||
When making TLS requests, Pkl comes with its own set of {uri-certificates}[CA certificates].
|
||||
These certificates can be overridden via either of the two options:
|
||||
|
||||
- Set them directly via the CLI option `--ca-certificates <path>`.
|
||||
- Add them to a directory at path `~/.pkl/cacerts/`.
|
||||
|
||||
Both these options will *replace* the default CA certificates bundled with Pkl. +
|
||||
The CLI option takes precedence over the certificates in `~/.pkl/cacerts/`. +
|
||||
Certificates need to be X.509 certificates in PEM format.
|
||||
124
docs/modules/pkl-cli/partials/cli-common-options.adoc
Normal file
124
docs/modules/pkl-cli/partials/cli-common-options.adoc
Normal file
@@ -0,0 +1,124 @@
|
||||
[[allowed-modules]]
|
||||
.--allowed-modules
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `pkl:,file:,modulepath:,https:,repl:,package:,projectpackage:` +
|
||||
Comma-separated list of 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.
|
||||
====
|
||||
|
||||
[[allowed-resources]]
|
||||
.--allowed-resources
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `env:,prop:,package:,projectpackage:` +
|
||||
Comma-separated list of URI patterns that determine which external resources can be read.
|
||||
Patterns are matched against the beginning of resource URIs.
|
||||
At least one pattern needs to match for a resource to be readable.
|
||||
====
|
||||
|
||||
[[cache-dir]]
|
||||
.--cache-dir
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `~/.pkl/cache` +
|
||||
Example: `/path/to/module/cache/` +
|
||||
The cache directory for storing packages.
|
||||
====
|
||||
|
||||
.--no-cache
|
||||
[%collapsible]
|
||||
====
|
||||
Disable cacheing of packages.
|
||||
====
|
||||
|
||||
.-e, --env-var
|
||||
[%collapsible]
|
||||
====
|
||||
Default: OS environment variables for the current process +
|
||||
Example: `MY_VAR=myValue` +
|
||||
Sets an environment variable that can be read by Pkl code with `read("env:<envVarName>")`.
|
||||
Repeat this option to set multiple environment variables.
|
||||
====
|
||||
|
||||
.-h, --help
|
||||
[%collapsible]
|
||||
====
|
||||
Display help information.
|
||||
====
|
||||
|
||||
.--module-path
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (empty) +
|
||||
Example: `dir1:zip1.zip:jar1.jar` +
|
||||
Directories, ZIP archives, or JAR archives to search when resolving `modulepath:` URIs.
|
||||
Paths are separated by the platform-specific path separator (`:` on *nix, `;` on Windows).
|
||||
Relative paths are resolved against the working directory.
|
||||
====
|
||||
|
||||
.-p, --property
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: `myProp=myValue` +
|
||||
Sets an external property that can be read by Pkl code with `read("prop:<propertyName>")`.
|
||||
Repeat this option to set multiple external properties.
|
||||
====
|
||||
|
||||
.--root-dir
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: `/some/path` +
|
||||
Root directory for `file:` modules and resources.
|
||||
If set, access to file-based modules and resources is restricted to those located under the specified root directory.
|
||||
Any symlinks are resolved before this check is performed.
|
||||
====
|
||||
|
||||
.--settings
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: `mySettings.pkl` +
|
||||
File path of the Pkl settings file to use.
|
||||
If not set, `~/.pkl/settings.pkl` or defaults specified in the `pkl.settings` standard library module are used.
|
||||
====
|
||||
|
||||
.-t, --timeout
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: `30` +
|
||||
Duration, in seconds, after which evaluation of a source module will be timed out.
|
||||
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]
|
||||
====
|
||||
Base path that relative module paths passed as command-line arguments are resolved against.
|
||||
Defaults to the current working directory.
|
||||
====
|
||||
|
||||
.--ca-certificates
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: `/some/path/certificates.pem` +
|
||||
Path to a file containing CA certificates to be used for TLS connections.
|
||||
|
||||
Setting this option replaces the existing set of CA certificates bundled into the CLI.
|
||||
Certificates need to be X.509 certificates in PEM format.
|
||||
|
||||
For other methods of configuring certificates, see xref:pkl-cli:index.adoc#ca-certs[CA Certificates].
|
||||
====
|
||||
26
docs/modules/pkl-cli/partials/cli-project-options.adoc
Normal file
26
docs/modules/pkl-cli/partials/cli-project-options.adoc
Normal file
@@ -0,0 +1,26 @@
|
||||
[[project-dir]]
|
||||
.--project-dir
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (none) +
|
||||
Example: `/some/path` +
|
||||
Directory where the project lives.
|
||||
|
||||
A project is a directory that contains a `PklProject` file, which is used to declare package dependencies, as well as common evaluator settings to be applied in the project.
|
||||
|
||||
If omitted, this is determined by searching up from the working directory for a directory that contains a `PklProject` file, until `--root-dir` or the file system root is reached.
|
||||
====
|
||||
|
||||
[[omit-project-settings]]
|
||||
.--omit-project-settings
|
||||
[%collapsible]
|
||||
====
|
||||
Disables loading evaluator settings from the PklProject file.
|
||||
====
|
||||
|
||||
[[no-project]]
|
||||
.--no-project
|
||||
[%collapsible]
|
||||
====
|
||||
Disables all behavior related to projects.
|
||||
====
|
||||
26
docs/modules/pkl-core/examples/CoreEvaluatorExample.java
Normal file
26
docs/modules/pkl-core/examples/CoreEvaluatorExample.java
Normal file
@@ -0,0 +1,26 @@
|
||||
import org.pkl.core.Evaluator;
|
||||
import org.pkl.core.ModuleSource;
|
||||
import java.util.List;
|
||||
|
||||
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"})
|
||||
public class CoreEvaluatorExample {
|
||||
@Test
|
||||
public void usage() {
|
||||
// tag::usage[]
|
||||
PModule module;
|
||||
try (var evaluator =
|
||||
Evaluator.preconfigured()) { // <1>
|
||||
module = evaluator.evaluate(
|
||||
ModuleSource.text("pigeon { age = 30; hobbies = List(\"swimming\", \"surfing\") }")); // <2>
|
||||
}
|
||||
var pigeon = (PObject) module.get("pigeon"); // <3>
|
||||
var className = pigeon.getClassInfo().getQualifiedName(); // <4>
|
||||
var hobbies = (List<String>) pigeon.get("hobbies"); // <5>
|
||||
// end::usage[]
|
||||
}
|
||||
}
|
||||
127
docs/modules/pkl-core/pages/index.adoc
Normal file
127
docs/modules/pkl-core/pages/index.adoc
Normal file
@@ -0,0 +1,127 @@
|
||||
= pkl-core Library
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-pkl-core-maven-module: {uri-maven-docsite}/artifact/org.pkl-lang/pkl-core
|
||||
:uri-pkl-core-main-sources: {uri-github-tree}/pkl-core/src/main/java/org/pkl/core
|
||||
:uri-pkl-core-test-sources: {uri-github-tree}/pkl-core/src/test/java/org/pkl/core
|
||||
:uri-pkl-core-Evaluator: {uri-pkl-core-main-sources}/Evaluator.java
|
||||
:uri-pkl-core-PModule: {uri-pkl-core-main-sources}/PModule.java
|
||||
:uri-pkl-core-PklException: {uri-pkl-core-main-sources}/PklException.java
|
||||
:uri-pkl-core-ValueVisitor: {uri-pkl-core-main-sources}/ValueVisitor.java
|
||||
:uri-pkl-core-JsonRenderer: {uri-pkl-core-main-sources}/JsonRenderer.java
|
||||
:uri-pkl-core-PcfRenderer: {uri-pkl-core-main-sources}/PcfRenderer.java
|
||||
:uri-pkl-core-PListRenderer: {uri-pkl-core-main-sources}/PListRenderer.java
|
||||
:uri-pkl-core-YamlRenderer: {uri-pkl-core-main-sources}/YamlRenderer.java
|
||||
:uri-pkl-core-SecurityManagers: {uri-pkl-core-main-sources}/SecurityManagers.java
|
||||
:uri-pkl-core-ModuleKeyFactories: {uri-pkl-core-main-sources}/module/ModuleKeyFactories.java
|
||||
|
||||
The _pkl-core_ library contains the Pkl parser, evaluator, REPL server, and xref:ROOT:standard-library.adoc[Standard Library].
|
||||
It is the foundation for most of Pkl's other libraries and tools.
|
||||
The library can also be used to embed Pkl in Java libraries and applications.
|
||||
|
||||
[[pkl-core-installation]]
|
||||
== Installation
|
||||
|
||||
The _pkl-core_ library is available {uri-pkl-core-maven-module}[from Maven Central].
|
||||
It requires Java 11 or higher.
|
||||
|
||||
=== Gradle
|
||||
|
||||
To use the library in a Gradle project, declare the following dependency:
|
||||
|
||||
[tabs]
|
||||
====
|
||||
Groovy::
|
||||
+
|
||||
.build.gradle
|
||||
[source,groovy,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile "org.pkl-lang:pkl-core:{pkl-artifact-version}"
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url "{uri-sonatype}" }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
.build.gradle.kts
|
||||
[source,kotlin,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile("org.pkl-lang:pkl-core:{pkl-artifact-version}")
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url = uri("{uri-sonatype}") }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
====
|
||||
|
||||
=== Maven
|
||||
|
||||
To use the library in a Maven project, declare the following dependency:
|
||||
|
||||
.pom.xml
|
||||
[source,xml,subs="+attributes"]
|
||||
----
|
||||
<project>
|
||||
<dependency>
|
||||
<groupId>org.pkl-lang</groupId>
|
||||
<artifactId>pkl-core</artifactId>
|
||||
<version>{pkl-artifact-version}</version>
|
||||
</dependency>
|
||||
ifndef::is-release-build[]
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>sonatype-s01</id>
|
||||
<name>Sonatype S01</name>
|
||||
<url>{uri-sonatype}</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
endif::[]
|
||||
</project>
|
||||
----
|
||||
|
||||
== Usage
|
||||
|
||||
{uri-pkl-core-Evaluator}[`Evaluator`] is the core evaluator that exposes multiple methods of evaluation.
|
||||
|
||||
The main evaluation method is `evaluate`, which returns a Java representation of the Pkl module object.
|
||||
If evaluation succeeds, a {uri-pkl-core-PModule}[`PModule`] object representing the fully evaluated module is returned.
|
||||
Otherwise, an {uri-pkl-core-PklException}[`PklException`] with error details is thrown.
|
||||
|
||||
Let's look at an example:
|
||||
|
||||
[[config-evaluator-core-example]]
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::{examplesdir}/CoreEvaluatorExample.java[tags=usage]
|
||||
----
|
||||
<1> Build an `Evaluator` with default configuration.
|
||||
The evaluator should be closed once it is no longer needed.
|
||||
In this example, this is done with a try-with-resources statement.
|
||||
Note that objects returned by the evaluator remain valid after calling `close()`.
|
||||
<2> Build a `ModuleSource` using the given text as the module's contents. Evaluate the given module source. Alternatively, it's possible to build a `ModuleSource` from a file, path, uri, and other sources.
|
||||
<3> Get the module's `"pigeon"` property, which is represented as `PObject` in Java.
|
||||
<4> Get the class name for this object. In this example, the class name is `pkl.base#Dynamic`.
|
||||
<5> Get pigeon's `"diet"` property, which is represented as `List<String>` in Java.
|
||||
|
||||
[[value-visitor]]
|
||||
Often, {uri-pkl-core-ValueVisitor}[`ValueVisitor`] is a better way to process a module.
|
||||
See {uri-pkl-core-PcfRenderer}[`PcfRenderer`], {uri-pkl-core-JsonRenderer}[`JsonRenderer`], {uri-pkl-core-YamlRenderer}[`YamlRenderer`] and {uri-pkl-core-PListRenderer}[`PListRenderer`] for examples.
|
||||
|
||||
[[security-manager-spi]]
|
||||
The (Pkl, not Java) security manager can be configured and customized using {uri-pkl-core-SecurityManagers}[`SecurityManagers`] and related classes.
|
||||
|
||||
[[module-loader-spi]]
|
||||
Module loaders can be configured and customized using {uri-pkl-core-ModuleKeyFactories}[`ModuleKeyFactories`] and related classes.
|
||||
|
||||
== Further Information
|
||||
|
||||
Refer to the Javadoc and sources published with the library, or browse the library's {uri-pkl-core-main-sources}[main] and {uri-pkl-core-test-sources}[test] sources.
|
||||
BIN
docs/modules/pkl-doc/assets/images/pkldoc-search.gif
Normal file
BIN
docs/modules/pkl-doc/assets/images/pkldoc-search.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 918 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user