Releases: google/jsonnet
v0.12.0
Stdlib changes:
- Fix
std.parseHex
that rejected certain correct inputs - Added
std.find
andstd.findSubstr
- Added
std.parseJson
Performance:
- C++ implementation desugarer now uses less stack space
- C++ implementation has native (faster) implementations of
std.join
,std.splitLimit
,std.substr
,std.range
std.strReplace
,std.asciiLower
,std.asciiUpper
Python
- jpathdir in Python bindings
Go
- New -c option will create directories for output files if necessary
v0.11.2
Note: v0.11.0 and v0.11.1 are the same as this release, but are botched due to mismatches in golden test files.
Language changes:
- std.native("foo") now returns null if foo doesn't exist, instead of an error. This is useful for falling back on Jsonnet implementations if a faster native one isn't available.
stdlib improvements:
- sort and set functions can now be given a "keyF" function for controlling the ordering
- std.trace for debugging
- std.parseHex
- std.parseOctal
C++ Implementation changes:
- Some performance improvements in garbage collection and static analysis
Go Implementation changes:
- Major (2x-10x) improvements in performance via a substantial refactoring of the interpreter
v0.10.0
Major changes
The formatter (jsonnet fmt
) is now more opinionated, in that more features are enabled by default. This means if you habitually use it to format your Jsonnet code, it may change them significantly after this release (hence the major version bump). We recommend reformatting your code to match these new defaults, but the old behavior is still available via:
jsonnet fmt -n 0 --string-style l --comment-style l --no-sort-imports
Native Go port
After a quiet ramp up, we're announcing the Go port. It is a complete re-implementation in Go, therefore it is more suitable for running untrusted Jsonnet code server-side. It is feature complete and will generate the same JSON and the only differences you might see are with some of the error messages and trace backs. We think it is ready for general use, and many projects are already using it.
You should stop using the cgo wrapper now!
Eventually, we would like to deprecate the C++ version, since the Go version has simpler source code (benefiting from go routines and the native garbage collector). However the formatter is still only available in C++ Jsonnet.
https://github.com/google/go-jsonnet
Minor additions:
- jsonnet -y and -m now respect -o
- JSONNET_PATH environment variable
{ [null]: true for x in [3] }
now respects thenull
instead of being an error- The parser takes much less stack space
std.strReplace(str, from, to)
std.isArray(v)
,std.isBoolean(v)
,std.isFunction(v)
,std.isNumber(v)
,std.isObject(v)
,std.isString(v)
std.sign(n)
std.asciiUpper(x)
,std.asciiLower(x)
std.manifestYamlDoc(value)
,std.manifestYamlStream(value)
std.manifestXmlJsonml(value)
(see jsonml.org)
...and minor bug fixes & performance improvements.
v0.9.5
One major change: Import paths now are properly escaped. This was originally an oversight and went unnoticed because people don't usually use backslashes in their paths. On Windows, we recommend using the verbatim string literals to avoid having to escape the path separator, e.g., import @"c:\foo.jsonnet"
.
Remaining changes are minor:
- Allow formatting of multiple files with a single jsonnet fmt invocation
- jsonnet fmt will now sort your imports alphabetically
- The Bazel Python build works again
- jsonnet fmt fixes code with mismatched newlines in { } and similar start/end syntax
- The Python bindings are now compatible with Python 3
- There is a VS2017 solution file
- The default -J paths were broken, now they include a proper "jsonnet" prefix. It's unlikely anyone was using them, since they were never advertised.
v0.9.4
Major changes:
There are two new operators e in e
and e in super
. They perform the same role as std.objectHasAll
, i.e. they allow you to discover whether a field exists, except that std.objectHasAll(super, e)
cannot be expressed since super
is not allowed in isolation. The semantics of e in super
are quite interesting because it returns false even if there is no super object.
There is a subtle change to the semantics of +:
and related field definitions. Previously if the super-object did not have the field f
then f +: e
was an error. Now, it succeeds in that case yielding f: e
. This extends recursively, so { } + { f+: { x +: { y: 1 } } }
yields { f: { x: { y: 1 } } }
, and in fact the left hand side { }
is not even needed. You can evaluate a mixin like { f+: { x +: { y: 1 } } }
without even applying it to anything. This is a backwards compatible change because it only affects the behavior of programs that used to fail.
Minor other changes in this release:
- Addition of std.prune
- Fix of uninitialized value (undefined behavior) in desugarer.
v0.9.3
Python-only release.
v0.9.2
Sorry for the churn. Since the last release a buffer overrun was identified, so this release fixes it. Also included are some fixes to jsonnet fmt behavior and a fix for [e::] when e was larger than one token.
v0.9.1
New features:
- error will implicitly convert to string
- Verbatim string literals, e.g. " \ " " can now be given as @" \ "" " (note the escaping of "
- std.md5("foo") is added.
Bug fixes:
Fixed the binding of self / super in e after the expansion of [e] +:
Several improvements to the output of jsonnet fmt when -n is used.
Avoid an infinite loop of memory consumption at a ||| syntax error.
v0.9.0
Fix a segfault in the GC when using native functions.
Some minor bug fixes.
Imported values are now cached after execution, resulting in a ~2x performance improvement (measured on some real Jsonnet code).
v0.8.9
This release renames all "library" jsonnet files to .libsonnet as proposed some months ago. This is just a convention, it does not affect evaluation of Jsonnet configs. As with all conventions, users can adopt it... or ignore it :)
This release also has some new language features:
Named params, default arguments
As in Python, you can provide default arguments to functions, e.g.
local add(x, y=3) = x + y;
add(6)
and also bind arguments to parameters by name instead of by position:
add(x=6)
The syntax and semantics matches Python but without _args and *_kwargs.
Top-level arguments
This is a more principled way of parameterizing an entire config. Previously the only way to do that was with std.extVar
, but this created a global variable of sorts. Code anywhere in the config could use it and it in large configs this can become a maintenance hurdle. std.extVar
still exists but there is a new way where the parameter is scoped only to the main or root file of the config, and has to be explicitly threaded to imported files:
Previously a Jsonnet file evaluating to a function would be rejected:
$ jsonnet -e 'function() 42'
RUNTIME ERROR: Couldn't manifest function in JSON output.
Now, such a function is called with no arguments to yield the value that is manifested as JSON. To add arguments, use the new commandline parameters.
Available options for specifying values of 'top-level arguments':
Provide the value as a string:
-A / --tla-str <var>[=<val>] If <val> is omitted, get from environment var <var>
--tla-str-file <var>=<file> Read the string from the file
Provide a value as Jsonnet code:
--tla-code <var>[=<code>] If <code> is omitted, get from environment var <var>
--tla-code-file <var>=<file> Read the code from the file
$ jsonnet -e 'function(a, b, c=3) a + b + c' --tla-code a=1 --tla-code b=2
6
Note that TLAs provide default arguments for the entire config, something that was not possible (but often requested) with std.extVar().
Native functions
Now you can, via the C API (or wrappers, e.g. Python) add your own native functions to Jsonnet. The purpose of these functions is to expose tricky functionality that you wouldn't want to implement in Jsonnet. E.g. compression, or encryption. Note that these functions must be pure. They must have no side-effects and must give the same return value for the same input. Since Jsonnet is a lazy language, native functions may be called at unusual times, in an unusual order, more times than expected, or not at all. If the functionality being exposed is not naturally pure (e.g. random secret generation), please wrap it in a cache so that subsequent calls with the same params give the same result.
Currently native extensions can have an arbitrary number of parameters but each has to be a primitive (i.e. not an object or an array). One option for now is to wrap the native function in Jsonnet code that calls std.toString() on the value, then parse the JSON on the host language side.
Native extensions can however return arbitrary JSON objects.