Introduction
Pkl(ぴっくる)はAppleが開発した、
OSSのconfig file生成用プログラミング言語です。
条件式やループなどの基本構文に加え、クラス・継承・抽象化などの
プログラミング言語機能も使えます。
pklファイルからJSON形式やYAML形式などの各種設定ファイルが出力可能で、
CLIツールや各言語のライブラリやプラグインとして使えます。
現状想定されているユースケースとしては、
下記のものがあります。
Generating Static Configuration(静的構成ファイル生成)
設定ファイルのgenerate機能です。
Pklで記述したコードをJSON、YAML、XML、プロティリスト形式で出力できます。
Application Runtime Configuration(アプリランタイム構成)
Pklをライブラリとして追加し、プログラム内で使用する機能です。
2024年2月時点ではJVM runtime(Java,Kotlin),Swift,Goに対応した
ライブラリが提供されています。
これらは今後追加されるみたいです。
今回はPklをインストールして、
Rustでビルド時にJSONファイルを生成してみます。
Environment
- MacBook Pro (13-inch, M1, 2020)
- OS : MacOS 13.5.2
- Rust : 1.75.0
Setup
各環境にあわせてPklをインストールします。
自分の環境では下記のようにインストールしました。
% curl -L -o pkl https://github.com/apple/pkl/releases/download/0.25.1/pkl-linux-aarch64
% chmod +x pkl
PklをPATHに追加してコマンドを実行してみます。
% pkl --version
Pkl 0.25.1 (macOS 14.1, native)
次にCargoでRustプロジェクトを作成します。
% cargo new pkl-example
あとで確認用に使うのでserdeを追加。
% cd pkl-example
% cargo add serde serde_json
プロジェクトのルートにintro.pklを下記内容で作成。
name = "Pkl: Configure your Systems in New Ways"
attendants = 100
isInteractive = true
amountLearned = 13.37
JSONで標準出力してみる。
% pkl eval -f json ./intro.pkl
{
"name": "Pkl: Configure your Systems in New Ways",
"attendants": 100,
"isInteractive": true,
"amountLearned": 13.37
}
Cargo.tomlにbuild.rsを指定しましょう。
[package]
・
・
build = "build.rs"
プロジェクトのルートにbuild.rsを作成します。
雑にpklのパスを設定してJSON出力コマンドを実行するだけです。
// build.rs
use std::process::Command;
use std::io;
use std::env;
fn main() -> io::Result<()> {
println!("build.rs start");
// 現在のPATHを取得してPATHにpkl追加&環境変数設定
let mut path = env::var_os("PATH").unwrap_or_default();
path.push(":");
path.push("<your pkl path>");
env::set_var("PATH", &path);
//pklコマンド実行(intro.json出力)
let output = Command::new("pkl")
.arg("eval")
.arg("-o")
.arg("./intro.json")
.arg("-f")
.arg("json")
.arg("./intro.pkl")
.output()?;
println!("{:?}",output);
if !output.status.success() {
panic!("Failed to execute pkl command");
}
Ok(())
}
src/main.rsでは生成されたjsonファイルにアクセスしてます。
use serde_json::Value;
use std::fs;
fn main() {
let data = fs::read_to_string("intro.json").unwrap();
let v: Value = serde_json::from_str(&data).unwrap();
// JSONデータにアクセスする
println!("name: {}", v.get("name").unwrap());
println!("attendants: {}", v.get("attendants").unwrap());
println!("isInteractive: {}", v.get("isInteractive").unwrap());
println!("amountLearned: {}", v.get("amountLearned").unwrap());
}
実行してみます。
jsonが出力されてアクセスできてます。
% cargo build -vv
% cargo run
・・・
name: "Pkl: Configure your Systems in New Ways"
attendants: 100
isInteractive: true
amountLearned: 13.37
Summary
build.rsからシンプルにpklコマンド実行してみました。
Rust用crateはそのうちでてくると思われるので
プログラム内からアクセスするのはもう少し待ちましょう。