jz list prints the table below from the binary you have. jz list df
shows the variants of one command and jz list df gnu everything about
one definition, including where it came from and how it detects its
input. Each variant below links to the JSON Schema of what it produces;
what each definition produces says what
those promise.
A handful of entries describe a shape rather than a command: table
(whitespace, aligned, box), csv (comma, tab), kv (colon,
equals) and ini (default). They are never chosen on their own —
two words above two words says nothing about what produced them — and
are reached by naming both halves:
$ sqlite3 -box app.db 'select * from users'| jz --parser table --variant box
$ jz --parser ini --file /etc/NetworkManager/NetworkManager.conf
They convert nothing: a shape says nothing about what its columns mean,
so every value is the text it was cut from. Use --define where you want
the same reading with settings of your own.
A variant is one output format of a command. GNU df, df -h, macOS
df and BusyBox df -h are four formats, so they are four definitions.
When several implementations print the same format, one definition covers
them and says so in its metadata.
Some commands print what another command prints. Nothing in the text says
which of them wrote it, so they share a definition rather than having one
each, and the command they are listed under is the one the definition is
named for. These are read as well:
Every definition has a JSON Schema of its output, derived from the
definition rather than written beside it: the keys are its columns,
groups and parts, the types are its field conversions, a key is required
when every object carries it, and a value may be null where the engine can
leave it empty (an aligned cell with nothing under it, a group that did not
take part, a value null_if names). A group that can only match a few
literals is an enum. Where the keys come from the input, as in a table
that names its columns from its header, the schema says what the values
look like instead of naming the keys.
$ jz list --schema df gnu
$ jz list --schema df gnu | jq '.items.required'
The schemas are published under
https://nao1215.github.io/jsonize/schemas/COMMAND/VARIANT.json, the
$id of each, and every fixture in the registry is checked against its
own on every change, by jz and by an independent validator.
x-jsonize.version is the version of that output contract. It is not
format, which versions how a definition is written; the two change for
unrelated reasons. A change a program reading the output could be broken
by — a key removed, a type changed or made nullable, an object become an
array, a key that is no longer always there or that now always is, a
value added to or taken from an enum — is refused unless the version
goes up with it. Adding a key that may appear is the one change that
keeps the version. The JSON jz prints carries no version: the definition
it was read with, which --explain names, identifies the contract.
The signature is a necessary condition. The operating system and the
arguments are known only when jz ran the command itself; they can then
remove candidates, never promote one. Exactly one survivor is a success.
Zero and more than one are errors that say what to pass.
Some formats are not evidence of anything. A number, a tab and a path
describes du output and git diff --numstat alike, and three numbers
in a row describe almost any table. Such a definition sets
auto_detect: false: it stays out of automatic detection and is used
when you name it, where its signature is still checked.
A rounded, human-readable number reaches JSON exactly as printed. The
base behind a suffix is not in the output (df -h steps by 1024, df -H
by 1000) and the value is rounded either way, so a byte count would be
two guesses stacked. Ask the command for exact numbers when you need
them: df, free, lsblk -b.
Where the exact and the rounded form of a command are separate
definitions, the exact one gives numbers: df does, df -h does not.
That split needs the two forms to be told apart, and telling them apart
means reading the values, which jz only sees for the first 200 lines. A
listing has no length limit, so ls -l and ls -lh are one definition
and its size is a string in both. The rule is the same one; what changes
is whether jz can know which form it has.
The same reasoning applies to env: a value containing a newline cannot
be told from two variables in the line-based output, so env -0 | jz
exists for the cases where that matters.
NAME=value is also what a .env file, a properties file and a shell
fragment look like, so the line-based form is one of the definitions jz
will not claim on sight. env | jz --parser env and jz run env read
it; env -0 is distinctive and needs no name.