Perl XS bindings to libjsonnet (Google Jsonnet C/C++ API).
This module provides a thin, low-level interface to the official Jsonnet VM. You can evaluate Jsonnet snippets/files, use multi/stream outputs, and register custom import and native callbacks from Perl.
This distribution requires libjsonnet (development headers and shared library).
You need:
libjsonnet.hlibjsonnet.so(or equivalent)- C++ standard library for linking (
libstdc++)
Jsonnet version 0.21.x or newer is recommended.
sudo apt install libjsonnet-dev jsonnetsudo dnf install jsonnet jsonnet-develsudo pacman -S jsonnetbrew install jsonnetgit clone https://github.com/google/jsonnet.git
cd jsonnet
make libjsonnet.so
sudo cp include/libjsonnet.h /usr/local/include/
sudo cp libjsonnet.so /usr/local/lib/
sudo ldconfig # on LinuxBefore need install cpanm
sudo apt install cpanmsudo dnf install cpanmsudo pacman -S cpanmbrew install cpanmcpanm Jsonnet::XSSet JSONNET_PREFIX so the build can find headers and library:
JSONNET_PREFIX=/opt/jsonnet cpanm Jsonnet::XSor when building from the repo:
JSONNET_PREFIX=/opt/jsonnet perl Makefile.PL
make
make test
make installThe build will also try pkg-config libjsonnet automatically when available.
use Jsonnet::XS;
my $vm = Jsonnet::XS->new(
ext_vars => { foo => "bar" },
);
my $json = $vm->evaluate_snippet("snippet", '{ x: std.extVar("foo") }');
print $json;my $json = $vm->evaluate_file("main.jsonnet");
print $json;Multi mode returns a hashref where keys are output filenames:
my $out = $vm->evaluate_file_multi("multi.jsonnet");
for my $name (sort keys %$out) {
print "== $name ==\n";
print $out->{$name};
}Stream mode returns an arrayref of JSON texts:
my $items = $vm->evaluate_snippet_stream("s", '[{a:1},{b:2}]');
for my $j (@$items) {
print $j;
}Register a custom importer. The callback must return:
($found_here, $content)on success(undef, $error_text)on failure
$vm->import_callback(sub {
my ($base, $rel) = @_;
# Example: virtual import
return ("virtual.jsonnet", '{ z: 42 }')
if $rel eq "virtual.jsonnet";
return (undef, "no such import: $rel");
});
my $json = $vm->evaluate_snippet("x", q'
local v = import "virtual.jsonnet";
{ z: v.z }
');
print $json;Note: once you set import_callback, it replaces the default importer.
If you want filesystem imports too, implement them in your callback.
$vm->native_callback(
"add",
sub { my ($a, $b) = @_; $a + $b },
[qw(a b)],
);
print $vm->evaluate_snippet("n", 'std.native("add")(2, 3)');Native callbacks accept primitive Jsonnet values (string/number/bool/null). Return values can be scalars, arrayrefs, hashrefs, or undef.
You can set tuning parameters either via constructor or later:
my $vm = Jsonnet::XS->new(
max_stack => 1000,
gc_min_objects => 10,
gc_growth_trigger => 2.5,
max_trace => 20,
string_output => 0,
);
$vm->jpath_add("./libsonnet");
$vm->ext_var("env", "prod");
$vm->tla_var("cfg", "value");string_output => 1 makes top-level Jsonnet strings return without JSON quotes.
Your Jsonnet.so was built without linking to libjsonnet.
Fix by installing libjsonnet-dev or rebuilding with a correct prefix:
JSONNET_PREFIX=/path/to/jsonnet perl Makefile.PL
make clean
make
make testor also can help:
cp libjsonnet.so.0 /usr/lib64/
cp include/libjsonnet.h /usr/include/Install the development package (libjsonnet-dev, jsonnet-devel) or
provide JSONNET_PREFIX.
Setting an import callback replaces default imports. Handle filesystem imports yourself if needed.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
Sergey Kovalev info@neolite.ru