Skip to content

v0.9.0

Latest

Choose a tag to compare

@github-actions github-actions released this 22 Sep 03:53
· 13 commits to main since this release
b553c48

This release adds sixteen definitions (the registry holds 280 commands through 758 definitions, from 270 and 742), makes an option either change the answer or be refused before anything is read, keeps the headings of a csv read as data as written, and fixes readers that returned JSON different from their input: YAML, JSON Lines, LTSV, local timestamps, folded lines and floats too small to hold.

Added

  • rsync --stats (rsync/stats): the transfer counts rsync prints at the end of a run, with the summary lines that follow them, as one object of typed numbers. The counts by kind that rsync prints in parentheses are read as an object of their own, and a kind it leaves out is null rather than zero. -v, -i, --progress and two or more -h options print something else and are refused.
  • 7z l -slt -ba (7z/list-technical-bare): the entry blocks 7-Zip prints with -ba, which leaves out the banner, the scan line, the archive name and the archive's own properties. An entry is the same object 7z/list-technical gives it; what differs is the whole, which is the array of them rather than an object holding the archive beside them.
  • openssl x509 -noout -text (openssl/x509-text): the version, the serial, the signature algorithm, the issuer, the subject, the two dates, the kind of key and its size, and one record per X509v3 extension with its critical mark and its value as printed. The key material and the signature are hexadecimal folded over a dozen lines or more and are not read; input.ignore names those lines, so --explain reports how many were left out.
  • tesseract IMAGE stdout tsv (tesseract/tsv): one row per page, block, paragraph, line and word, with the box each occupies and, for a word, its confidence. A row that is not a word prints -1 for the confidence, which is tesseract's own value and stays the number it printed. hocr, alto, pdf and the plain text tesseract writes when no configuration is named are other formats and are refused.
  • Seven definitions for time zones, the SSH client and the desktop: zdump (zdump/current) and zdump -v / -V (zdump/verbose, which keeps the lines where gmtime or localtime failed, with the seconds they failed on), ssh -G HOST (ssh/config-dump, a list of name and value, so a keyword given more than once such as identityfile or localforward keeps every value), xwininfo (xwininfo/stats), usb-devices (usb-devices/linux, one object per device with its interfaces and their endpoints), glxinfo -B (glxinfo/brief) and eglinfo -B (eglinfo/brief, one record per platform and per device, holding the errors a platform printed).
  • Five definitions: lscpu -p (lscpu/parsable, the columns named by the header comment, so any -p=LIST is read, and a row whose cache IDs lscpu left out is refused rather than shifted), gcc -print-search-dirs (gcc/print-search-dirs, also under g++, with the program and library paths as arrays), apt-cache rdepends (apt-cache/rdepends, marking an alternative and the other packages that satisfy the same dependency), pw-cli ls (pw-cli/list-objects, one record per PipeWire object with its properties), and xprop -root / xprop -id (xprop/default, one record per property, with the lines printed under it kept). The registry holds 280 commands through 758 definitions.
  • A server-side group in the cookbook: inspecting an uploaded PDF with pdfinfo, an archive with 7z l -slt, a certificate with openssl x509, an upload's type with file -i, and recording what a backup run moved with rsync --stats, closing with the jz run exit-status contract and what converting the output does not do. The five commands run for real in the end-to-end suite on Linux, over paths holding a space and shell metacharacters, with their failure cases.
  • group_separator on an int or a float field: the one character a format writes between groups of three digits. It is removed only where the digits are grouped by it, so a value of another shape is an error rather than a number made by dropping characters. It is for a format that decides the character itself; a count printed with the separator of the user's locale still stays the string it was printed as.

Changed

  • An option either changes the answer or is refused with exit 2 before anything is read or run. --raw, --assume-year and --assume-zone are now refused for a data format (--format or a data file's extension), which is read without a definition's field rules and so could change nothing, and --assume-year and --assume-zone are refused when no variant of the named parser, or the --define, prints a timestamp they could complete (jz run --assume-year now df), the way a key to --extract none of them has already was. --assume-year and --assume-zone beside --raw are refused as --type beside it is, since --raw leaves a timestamp as the text it was cut as. When the definition is found from the text, an option it has no use for still passes, since which definition reads the input is not known until it has been read.
  • The header line of a csv or tsv read as data (--format csv, a .csv file, jz new k:=@x.csv, --stream) is now the keys as written: 名前, In Stock and %CPU stay as they are, where they became column, in_stock and cpu_percent. An empty heading is still column and a repeated one a_2. --parser csv, which reads with a definition, normalises the headings as before.
  • jz list df/gnu and jz list --schema df/gnu take the name --explain and jz list print for a definition. A path such as /usr/bin/df is still read as the program it names.
  • An ini section heading with no name ([]) is an error. It merged into the keys written before the first heading, which go under the empty name.

Fixed

  • apt-cache/depends refused the line of a relationship ORed with the next one ( |PreDepends: coreutils-from-uutils), so jz run apt-cache depends coreutils was exit 3. The mark is now read into alternative, which is true for such a relationship and false for the others.
  • apt-cache/depends claimed the output of apt-cache rdepends -o APT::Cache::ShowDependencyType=true, then failed on its Reverse Depends: line with exit 3. It now leaves that output to apt-cache/rdepends.
  • gpg/list-keys refused a user ID whose validity gpg pads on both sides ([ full ]), which is how a key signed into full validity is listed, with exit 3.
  • A time field with location: local moved a wall clock the zone skips to another hour. With TZ=America/New_York, 2025-03-09 02:30 came out as 2025-03-09T01:30:00-05:00, the same answer as for 01:30, because time.ParseInLocation normalises the hour a change to summer time skips. The value is now refused with exit 3.
  • input.fold joined a continuation onto a blank line above it, so a, an empty line and an indented b gave a record " b" with a space the text does not hold. A blank line is now nothing to join onto, in the whole reading and in --stream alike, and the continuation is an error naming its line.
  • A float field, and --type COLUMN=float, wrote 0 for a value too small for a 64-bit float (1e-400), while one too large was refused. Both are now refused with exit 3.
  • The error for a tree line that skips a level gave the wrong levels: a followed by a line indented twice said "indented 1 levels below a line at level 1". It now says the line is at level 2 under a line at level 0, and a first line that is indented says there is no line above it.
  • jz list dff did not suggest df, although jz run dff and --parser dff do. jz list now gives the same suggestion.
  • YAML: the value of an explicit key written on the line of its ":" was read as one string when it opened a collection there. ? a followed by : - x and an indented - y gave {"a":"- x - y"} with exit 0; it is now the list ["x","y"], and : b: 1 is a mapping.
  • YAML: a sequence item written on the line of its key, a: - b, was read as the string "- b". The same happened with - 1 inside a flow sequence and with ? b used where a value belongs. YAML does not allow a plain scalar to start with an indicator and a space, and other readers refuse the line; jz now refuses it with exit 3 and says to start the items on the next line.
  • YAML: a comment did not end a plain scalar written over several lines. a: x # note followed by an indented y gave "x y", keeping the text after the comment; the indented line is now refused as unexpected indentation.
  • YAML: a literal or folded scalar at the end of a text without a final line break gained one. a: | over x with no newline after it gave "x\n"; the break a scalar keeps is the one its last line has, so it is now "x".
  • JSON Lines, LTSV and jz new --each skipped any line of Unicode white space. A line holding only a no-break space, an ideographic space, a form feed or a vertical tab disappeared with exit 0, although none of these is white space in JSON, and --format json refuses the same text. Only a line of JSON's white space, spaces, tabs and carriage returns, is blank in JSON Lines now; LTSV skips only an empty line and, as its reference says, refuses a line of spaces as a field without a label.
  • jz run go test -bench=Parse was exit 4. go/bench required -bench or the literal -bench=., and an argument written with = is matched by its name and the =, so any other value left it without a candidate. go/bench now takes -bench= and the two-dash spellings, and go/test refuses them.
  • FuzzReadJSON reported an escape naming half of a surrogate pair as valid JSON the reader refused, so make fuzz failed on every run that reached that input. json.Valid accepts such a document and json.Unmarshal then hands back U+FFFD, which is a character the input may hold for itself, so refusing it is what keeps a conversion from changing what it was given. The fuzz target now names it among the refusals it expects, beside a key given twice, a document nested past the limit and text that is not UTF-8, and the input is in the seed corpus.
  • file/posix refused a listing whose path holds a space. The signature required a path of non-space characters, although the expression that reads the line has always taken [^:]+, so file 'quarterly report.pdf' was exit 4.
  • jz run file -i FILE could land on file/posix. file(1) reports a file it cannot open in the description and still exits 0, and that sentence satisfied file/posix because "No such file or directory" holds the word "directory", so a caller that asked for a MIME type was handed a record with a type instead. file/posix now states that it does not read the output of -i, --mime, --mime-type, --mime-encoding, --extension or --apple, and the answer is exit 4 with a diagnostic saying so.