Releases: 01mf02/jaq
1.3
This release makes jaq a lot lazier. In particular, several core filters, such as debug
, are now evaluated as late as possible #131, and filters passed to path expressions are now also executed lazily #150. That means that many filters which did not terminate before now terminate!
Backwards-compatible additions
Thanks go especially to @kklingenberg for implementing several new functionalities!
- Support for recursive object merging via
a * b
by @kklingenberg #130 - Add
env
filter and$ENV
variables by @kklingenberg #128 - Extend path syntax to support paths like
.a.[]
#145 group_by
terminates as soon as there is an error #129
Breaking Changes
- The
last(f)
filter now returns no output instead ofnull
whenf
yields no output. This is to make it consistent withfirst(f)
, which has the same behaviour. 51d3f51 - Rename
--compact
to--compact-output
to match jq #148 to_entries
andpaths
now return objects without sorting keys, like jq 484dd27
Eliminated bugs
- Calling jaq without a filter now correctly executes the identity filter #147
- Calling jaq with an empty filter (
''
) now yields an error message instead of crashing, thanks to a newariadne
release --- thanks to @zesterer! - Processing long sequences with
foreach
used to crash with a stack overflow at the end, for example when executingforeach limit(1000000; repeat(1)) as $x (0; .+$x)
. This is now not longer the case. 854d22c
Full Changelog: v1.2.0...v1.3.0
1.2
jaq is a jq clone with an emphasis on correctness, speed, and simplicity.
This release brings initial support for tail-recursion optimisation. For example, the filter
def repeat(f): def rec: f, rec; rec; repeat(1)
yielded a stack overflow after several values in jaq before. Now, jaq will actually yield an infinite stream of ones.
As a result, several filters have been rewritten to leverage tail-recursion optimisation, in particular repeat
and paths
. The filters recurse
, while
, and until
, which previously had to be implemented as native filters, are now implemented by definition, which significantly simplifies the code base.
Furthermore, a few filters are now executed more lazily, including array construction ([...]
) and reduce
/foreach
/for
. For example, the filters
def f: 1, [f]; limit(1; f)
and
def f: f; limit(1; foreach (0, f) as $x (1; .))
yielded a stack overflow in jaq before. Now, both just return 1, like jq.
Finally, as cherry on the icing, jaq now implements the range/3
filter and range/2
supports more maximal elements. For example, range(1; 10; 2)
yields 1, 3, 5, 7, 9
, and range(0; infinite)
now yields the (infinite) stream of all natural numbers.
Full Changelog: v1.1.2...v1.2.0
1.1.2
Like jaq 1.1.1, this is a maintenance release without new features.
It decreases the minimal supported Rust version (MSRV) to allow building jaq on Rust versions as low as 1.64 (released Sept. 22, 2022).
Some parts of jaq, like the interpreter and the core library, now build even with Rust 1.63.
1.1.1
jaq 1.1 did not build on Rust 1.62 anymore due to some new versions of dependencies.
Therefore, jaq 1.1.1 downgrades a few dependencies so that it builds at least on Rust 1.65.
This is now automatically verified by a GitHub action.
Apart from this, this release contains no new functionality.
New Contributors
Full Changelog: v1.1.0...v1.1.1
1.1
jaq is a jq clone with an emphasis on correctness, speed, and simplicity.
The largest change in jaq 1.1 is the support for filter arguments in recursive filters. This means that you can now write something like:
def repeat(f): f, repeat(f); repeat(1, 2)
However, unlike in jq, this specific example will currently fail with a stack overflow after a certain number of values (about 12,000 on my machine). To address this issue, tail-call optimisation is necessary, which is planned to be supported in jaq 1.2.
Furthermore, several expressions that were evaluated strictly are now evaluated lazily, in particular cartesian products and objects.
That means that some filters that would previously never yield any input, now can yield an infinite number of inputs.
The API of jaq 1.1 is fully backwards compatible with the API of jaq 1.0.
Full Changelog: v1.0.0...v1.1.0
1.0
jaq is a jq clone with an emphasis on correctness, speed, and simplicity.
jaq 1.0 brings lots of features compared to the last stable release (0.10).
A short summary with examples:
- Recursive/nested function definitions:
def walk(f): def rec: (.[]? |= rec) | f; rec;
- Variable arguments:
def foo($v; f): ...
- String interpolation:
@uri "https://www.google.com/search?q=\(.search)"
- if-then expressions without else branch:
if . < 0 then - . end
- try-catch expressions:
try . * 10 catch "NaN"
- Many, many new filters
- Native filter API: allows you to create custom versions of jaq where you can supply your own filters written in Rust
- Automatically built binaries
For more details on these changes, see the alpha, beta, and gamma release information.
Given that this is an 1.0 release, I will try to maintain a stable API.
Among others, future improvements that should be possible within the current API include optimisation of tail recursive calls (for better recursion performance) as well as parallel execution.
Thanks again to all contributors since the last stable release!
Full Changelog: v1.0.0-gamma...v1.0.0
1.0 gamma
This release brings support for string interpolation, including custom formatters (thanks to @kklingenberg). That means that you can now write something like @uri "https://www.google.com/search?q=\(.search)"
and have it interpreted like in jq.
Furthermore, like in the upcoming jq 1.7, else
branches in if-then-else expressions can now be omitted.
This version is planned to be the last one before 1.0. No new features are supposed to be integrated into 1.0, only bug fixes.
From this release on, binaries are automatically built. It would be great if someone with an Apple system could test it on their machine.
Smaller changes
Full Changelog: v1.0.0-beta...v1.0.0-gamma
1.0 beta
This release includes a large number of new filters, mostly for:
- strings (@baod-rate, #84, #82),
- arrays (@kklingenberg #74),
- dates (@baod-rate, #85), and
- math (@kklingenberg, #96).
Furthermore, it adds support for the try f catch g
syntax (@kklingenberg, #100), and strings can now be multiplied with integers to repeat them (@nouritsu, #86).
The CLI supports the option --nul-output
(@baod-rate, #91) and matches jq’s exit code with --exit-status
when there is no output (@baod-rate, #92).
Under the hood, the API has changed considerably in order to accommodate for the changes implied by native filters. Most notably, the jaq-interpret crate (containing the interpreter, i.e. the heart of jaq) was split off from jaq-core, and the jaq-syn crate (containing only data types for the syntax) was split off from jaq-parse.
Thanks again to @baod-rate and @kklingenberg for their tremendous efforts!
New Contributors
- @baod-rate made their first contribution in #80
- @nouritsu made their first contribution in #86
- @kklingenberg made their first contribution in #74
Full Changelog: v1.0.0-alpha...v1.0.0-beta
0.10.1
This release fixes a critical bug that can occur when binding multiple variables. Furthermore, it uses a newer version of the regex crate to allow for a simpler installation.
Full Changelog: v0.10.0...v0.10.1
1.0 alpha
This release adds a lot of new features to jaq:
- Recursive & nested functions: see the README for restrictions of recursive functions
- Variable arguments:
def foo($v; f): ...
- Variables bound via command-line arguments (
--arg
) can be referred to from definitions now - New filters:
walk(f)
,group_by(f)
,unique
,unique_by(f)
,paths
- Tests (
--run-tests
)
Thanks are due especially to @passcod for having implemented native filters. Users that use jaq as part of their own programs via the API can now implement filters as Rust functions and expose them to jaq. The API is still subject to change, see #70.
Given the extent of these new features, I think that the time is ripe for a 1.0 release.
However, this is an alpha release because especially recursive/nested functions have not yet received the amount of testing that I would expect from a 1.0 release.
As I will be going this week on a cycling trip that will last about two months, I will not be available during this time to address issues myself. However, it is my hope that this time allows users to test the new functions and to report issues (and in the optimal case submit PRs to fix the problems), in order to allow for a more polished 1.0 release later.
New Contributors
- @Shirtpantswallet made their first contribution in #65
- @passcod made their first contribution in #70
Full Changelog: v0.10.0...v1.0.0-alpha