Commit graph

237 commits

Author SHA1 Message Date
John Kerl
fdcca41536
Add --right-align-numeric for PPRINT and Markdown output (#1503) (#2161)
For PPRINT, right-justifies data cells whose values are numeric,
leaving other cells and header lines left-justified. For Markdown,
emits right-alignment markers (---:) for numeric columns; in
--omd-aligned mode also right-justifies the raw cell text.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 15:02:18 -04:00
John Kerl
ac08b072dc
Honor --ors crlf for CSV output (#1810) (#2150)
* Honor --ors CRLF for CSV output (#1810)

The full-CSV record writer validated ORS as newline or
carriage-return/newline, but never propagated the choice to the forked
Go CSV writer's UseCRLF field, so `--ors '\r\n'` (or `--ors crlf`)
silently produced LF line endings. Set UseCRLF from the writer options
so CRLF output is honored. Default behavior (LF) is unchanged, and
other ORS values are still rejected. The CSV-lite and TSV writers
already honored CRLF ORS.

Also: fix a copy-paste "for CSV" in the TSV writer's ORS-validation
message, add unit tests asserting byte-exact line endings (the regtest
harness normalizes CR/LF, so this can't be asserted in test/cases), add
CLI-level regression cases, and update the separators documentation.

This substantially addresses #1722 as well: RFC-4180-style CRLF output
can now be requested on any platform.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Fix errcheck lint: check Flush() error in CSV writer test

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 20:35:32 -04:00
John Kerl
c6986f90e9
Document meaning of hyphenated field_type values in mlr summary (#1082) (#2149)
The summary verb's field_type column shows values like "string-int" or
"empty-string" for columns containing values of mixed inferred types:
all types encountered across records are printed, hyphen-joined, in the
order first encountered. Add a note to the verb's help text explaining
this, and regenerate the man page, docs, and golden test output.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 20:34:16 -04:00
John Kerl
66e6d00182
join: document --icsv etc. as accepted left-file format flags (#444) (#2143)
The join verb's help text listed only '-i {one of csv,dkvp,nidx,pprint,xtab}'
for overriding the left-file input format, but the verb also accepts the
--icsv/--ijson-style main-flag shorthands (and formats beyond the five
listed, e.g. json and tsv), since unrecognized verb flags fall through to
the main flag table. Update the usage text to say so, and regenerate the
man page and docs content that embed this help output.

Fixes #444.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 20:10:49 -04:00
John Kerl
a5df7967b2
uniq: document that -g/-f output-field order follows the command line (#962) (#2145)
The uniq verb writes its group-by fields in the order they are named
with -g or -f, not in the order they appear in the input records
(unlike cut, which preserves input order unless -o is given). Per
discussion on #962, document this in the verb help text rather than
change long-standing output ordering. Regenerate the man page and the
docs pages which embed the verb help.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 20:09:26 -04:00
John Kerl
34da987dc2 Post-6.20.2 release: back to 6.20.2-dev 2026-07-04 15:44:14 -04:00
John Kerl
f5a799f630 Prepare 6.20.2 release 2026-07-04 14:59:19 -04:00
John Kerl
12131ea755
Miller 6.20.1 (#2138)
* Miller 6.20.1

* make dev
2026-07-04 09:59:15 -04:00
John Kerl
486f013870 Post-6.20.0 release: back to 6.20.0-dev 2026-07-03 20:55:25 -04:00
John Kerl
9a1c49be76 Prepare 6.20.0 release 2026-07-03 20:39:31 -04:00
John Kerl
a9de5824ba
docs: add "Miller and AI" page (#2098) (#2134)
* docs: add "Miller and AI agents" quick-start page (#2098)

Umbrella page for the AI-friendly feature stack: one-line MCP setup as
the fast path, plus the plain-CLI path (which, help --as-json,
describe, --explain, --errors-json, --no-shell) with live CI-tested
examples, and the discover -> constrain -> validate -> run loop.
Cross-linked with the MCP server page; listed under Getting started.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: reframe AI page as "Miller and AI" (#2098)

Rename ai-agents.md to ai.md and restructure around the pre-MCP
feature stack, organized as the loop each feature serves: Discover
(catalog/index/which, cache keys, single-sourced usage text),
Constrain (enum value-sets + describe: tool shape vs data shape),
Validate (--explain), Run and recover (--errors-json, --no-shell,
env-var trio). MCP is now one closing section pointing at the
mcp-server.md detail page. All examples are live and CI-tested,
including Miller querying its own catalog.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: retitle MCP page to "The MCP server" under the Miller-and-AI umbrella

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: add bare-minimum getting-started section to Miller-and-AI page

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: AI features land in Miller 6.20

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: hyperlink SKILL.md references to the repo

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: rename section to 'The essentials'

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 20:31:20 -04:00
John Kerl
41f5188bd0
Add mlr mcp MCP server + agent playbook, with a --no-shell gate (#2098 PR7) (#2133)
* Plan: flesh out PR7 (MCP server + Agent Skill) design

stdio transport (no HTTP port), mlr mcp terminal in the main binary,
SDK-vs-handroll decision, tool list, in-process vs subprocess split,
run-tool safety (--no-shell prerequisite), single-sourced skill, tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add mlr mcp: MCP server + agent playbook; --no-shell gate (#2098 PR7)

New terminal `mlr mcp` runs a Model Context Protocol server over stdio
(spawned by MCP clients; no network port), exposing five tools --
list_capabilities, which, validate_dsl, describe_data, run -- plus an
agent playbook as MCP prompt/resource. Catalog tools are served
in-process from the help registries; the rest subprocess this same
binary with MLR_ERRORS_JSON=1, a timeout, and an output cap.

Prerequisite: a new --no-shell flag / MLR_NO_SHELL env var (one-way
gate) disables the DSL system/exec functions, piped redirects, and
--prepipe/--prepipex; the MCP server sets it on the commands it runs
unless started with --allow-shell.

Adds the github.com/modelcontextprotocol/go-sdk dependency.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Force LF checkout for the embedded SKILL.md (Windows CI fix)

go:embed embeds checkout bytes, so a CRLF checkout on Windows made the
embedded playbook differ per platform and failed
TestPlaybookHasFrontmatter. Pin the file to eol=lf in .gitattributes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Move no-shell test DSL into per-case mlr files (Windows CI fix)

Inline single-quoted DSL in cmd files is mangled by the Windows shell
(single quotes are not quote characters there); the harness's
put -f ${CASEDIR}/mlr pattern avoids shell quoting entirely.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 19:41:49 -04:00
John Kerl
d415ca7655
Add mlr describe schema/shape introspection verb (#2098 PR6) (#2132)
One output record per input field: types seen with counts, occurrence
count, null count, cardinality, min/max, and -- for fields within the
-n/--max-values cap -- the complete distinct-value list in first-seen
order. `mlr --ojson describe` is the machine-readable form; nested
types/values flatten in tabular formats.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 18:43:49 -04:00
John Kerl
7f60e7da57
Add DSL validate/dry-run: put/filter --explain (#2098 PR5) (#2131)
Lets an agent type-check a DSL expression before spending a full input
pass. `mlr put --explain '...'` (and filter) runs the existing
parse -> ValidateAST -> CST build -> Resolve path, then:

- valid: prints "mlr {put,filter}: DSL expression is valid." and exits 0
- invalid: returns the build error up the normal path, so --errors-json
  emits a structured document; exits 1
- -W with fatal warnings: reports and exits 1

The gate lives in the pass-two constructor, before any input file is
opened, so no input stream is read (verified with a nonexistent input
file still validating OK).

Also categorize bare "parse error: ..." messages from the DSL parser as
kind "dsl-parse-error" rather than "generic" (climain/errors_json.go),
so --explain --errors-json gives an agent a useful error kind. The CSV
reader's "parse error on line ..." is stream-time and never reaches this
command-line-parse categorizer.

Tests: dsl-explain/0001-0004 regression cases (valid put/filter, invalid
plain, invalid --errors-json) and categorize unit tests. Regenerated
verb docs, manpage, and the help usage-verbs golden case.

The older -X ("exit after parsing") still exits 0 even on a parse error;
left as-is since --explain is the correct validation path.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 18:12:23 -04:00
John Kerl
12c96298b9
Add a first-class bytes type to the DSL, with b"..." literals and base64/hex codecs (#2122)
* Add MT_BYTES mlrval type: foundation and disposition tables

First step toward a first-class bytes type in the DSL (#1231).
Adds MT_BYTES (payload []byte, rendered as lowercase hex in all output
formats, JSON-encoded as a hex string), extends every disposition
matrix/vector with the new row/column -- real cells for comparison,
sorting, and dot-concat of bytes with bytes; type-error stubs
elsewhere -- and adds sweep tests asserting no table has nil cells,
since Go zero-fills short array literals when MT_DIM grows.

Bytes values are not yet constructible from the DSL; b"..." literals
and constructor/codec functions follow in subsequent commits.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add b"..." bytes-literal syntax to the DSL

Adds a bytes_literal token to the grammar (regenerating the PGPG lexer
and parser) and a BytesLiteralNode in the CST which evaluates to an
MT_BYTES mlrval. Escape handling reuses UnbackslashStringLiteral,
which is already byte-oriented: b"\xff" is the single byte 0xff.
Unlike string literals, bytes literals never participate in
regex-capture replacement. A bare identifier b is unaffected.

Part of #1231.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add bytes DSL functions: conversions, codecs, and bytes-aware built-ins

- bytes(x) converts strings to bytes; string(b) reinterprets raw bytes
  as UTF-8 text (the reverse)
- base64_decode now always returns bytes (superseding the interim
  string-or-hex behavior); base64_encode accepts string or bytes
- New hex_encode/hex_decode functions
- is_bytes and asserting_bytes predicates
- md5/sha1/sha256/sha512 accept bytes, hashing the raw payload
- strlen of bytes is the byte count; substr/substr0/substr1 on bytes
  slice by byte position and return bytes

The Cyrillic-LDAP scenario from #1231 now works without exec
workarounds: string(base64_decode($x)) recovers the text, and binary
payloads survive undamaged as bytes.

Closes #1231.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add bytes-type docs and regression cases

Documents the bytes type on the data-types page, regenerates the
function-reference/man-page material, and adds regression coverage:
literal escape forms, operators (concat/compare/slice/sort and
type errors), conversions and codec round-trips, and CSV-to-JSON
output rendering of bytes fields.

Part of #1231.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Reposition MT_BYTES to sort adjacent to MT_STRING in the type enum

MT_BYTES was appended after MT_ABSENT for index stability; move it
right after MT_STRING instead, since that's where it conceptually
belongs and where it already sorts in the cmp disposition matrices.
Mechanically re-derive all ~40 disposition tables in pkg/bifs and
pkg/mlrval accordingly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix windows CI

* fix merge

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 11:58:44 -04:00
John Kerl
7e1c9b4119
Next batch of lint fixes (#2108) 2026-06-28 17:36:36 -04:00
John Kerl
809d312bd4
Add long-over --md flag (#2100) 2026-06-24 13:58:12 -04:00
John Kerl
88286fd1b4 Post-6.19.0 release: back to 6.19.0-dev 2026-06-19 19:34:20 -04:00
John Kerl
0c675ee6da Prepare 6.19.0 release 2026-06-19 18:28:13 -04:00
John Kerl
86c8097dc2
Default to "cat" verb when none is supplied (#2060)
* Default to "cat" verb when none is supplied (#2029)

Invocations like 'mlr --j2y' or 'mlr --c2p' previously failed with
"no verb supplied", forcing users to type the trailing 'cat'
explicitly for pure format conversions. Default the verb to 'cat'
in that case. Bare 'mlr' with no flags, no verb, and no files
still prints the main usage banner.

This handles flag-only invocations (e.g. 'mlr --c2j < input.csv'
or 'mlr --c2j --from input.csv'). File names without a preceding
verb are still parsed as verb candidates and continue to error if
not found; that broader change is out of scope here.

* Use ${MLR} substitution for bare-mlr regression case (#2029)

The regtester only substitutes the mlr executable when the cmd
starts with "mlr " (with a trailing space). The bare-mlr usage-banner
test had a cmd of just "mlr", so on CI -- which invokes regtest with
a relative path like 'test/../mlr' -- the test shelled out to a
literal 'mlr' that isn't on PATH and failed with exit 127.

Switch the cmd to ${MLR} (the regtester's explicit substitution
token) so the case runs the right binary in any invocation context.
2026-05-17 12:13:21 -04:00
John Kerl
e0cf596853
Add --omd-aligned flag for column-padded markdown output (#2057)
Adds a new Markdown-only flag --omd-aligned (alias --omarkdown-aligned)
that left-justifies cells and pads each column to a uniform width.
The rendered table is unaffected; the goal is readability of the raw
markdown source. The flag implies --omd, so users do not need to pass
both.

Implementation batches records by schema (like pprint), computes max
column widths, then emits header / separator / data rows with bars
vertically aligned. Default markdown writer behavior is unchanged.
2026-05-16 11:41:01 -04:00
John Kerl
9a25ba5dfa Post-6.18.1 release: back to 6.18.1-dev 2026-04-19 12:03:05 -04:00
John Kerl
22bed96346 Prepare 6.18.1 release 2026-04-19 11:41:48 -04:00
John Kerl
1a50215d3d
Add a ./tools/release.sh script (#2043)
* tools/release.sh

* Updates doc page re release script

* testing

* Prepare 6.18.0 release
2026-04-19 10:43:01 -04:00
John Kerl
3e429f5b42
Use "\n" in replace for gsub and sub (#2042)
* Fix issue 1805

* Run `make dev`
2026-04-19 10:21:51 -04:00
John Kerl
0395cbddc6
Run make dev after PR #2026 (#2027) 2026-04-08 08:50:39 -04:00
John Kerl
af1adf80ad
Replace GOCC parser-generator with PGPG (#2015)
* Porting

* Update some tests that depend on AST-print output

* iterating on GOCC -> PGPG

* iterating

* iterating

* iterating

* iterating

* iterating

* Modify expout files that need only AST-print-syntax updates

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* sync test cases from mlr-6.17.0, except AST-prints ...

* sync test cases from mlr-6.17.0, except AST-prints ...

* Fix lashed emit for $* and @*

* Fix --1 and ++1 chained unary ops

* Emit with function callsite

* test cases

* dot operator

* M_PI and M_E

* Iterating on lashed emit cases

* error-wording differences

* rm some should-fail files

* Fix issue with leading semicolon

* trailing comma in func params; most AST-print deltas

* error-wording delta

* fix unset all

* AST-print deltas

* go mod tidy: forced `go 1.25` to `go 1.25.0`

* Depend on PGPG v1.0.0

* Fix Windows CI failure

* Remove cmd/experiments/dsl_parser

* GOCC -> PGPG

* neaten

* Fix regex issue found in doc gen
2026-03-15 22:28:57 -04:00
John Kerl
f8a8f29584
Experiment with mlr script (#2009) 2026-03-05 20:14:32 -05:00
John Kerl
102c624cee
Add DKVPX file format (#2002)
* Initial DKVPX parser

* pkg/input/record_reader_dkvpx*go

* pkg/output/record_writer_dkvpx.go

* docs update

* make fmt

* perf note
2026-03-02 22:35:08 -05:00
John Kerl
cd39c4e1bd
make dev ater PR 1984 (#1985) 2026-02-21 23:24:20 -05:00
John Kerl
47ca5eb88a Post-6.17.0 2026-02-21 09:40:15 -05:00
John Kerl
dc00aa3e16 Miller 6.17.0 2026-02-21 09:16:55 -05:00
John Kerl
daae7ff7f0
Add DCF (Debian Control Format) as supported file type (#1970)
* reader

* record writer

* pkg/output/record_writer_dcf.go

* test/input/test.dcf

* test/cases/io-dcf/

* pkg/cli/option_parse.go

* make fmt

* make dev

* docs and `make dev`
2026-02-16 11:10:39 -05:00
John Kerl
f375440bd4
Support YAML I/O (#1963)
* docs/src/proposal-yaml-io.md

* initial step

* Add `--y2c` etc

* test cases

* docs

* more testing

* more

* more test cases

* git rm docs/src/proposal-yaml-io.md

* make dev

* ylistwrap -> yarray
2026-02-15 09:24:38 -05:00
John Kerl
0003b83654
mlr split with --folder (#1962) 2026-02-14 20:22:24 -05:00
John Kerl
26600f77aa
Add -r (for regex field-name matching) to mlr nest (#1961)
* initial attempt

* fix up cli flag

* make dev
2026-02-14 19:59:51 -05:00
John Kerl
5e0114e0cf
mlr reorder -r (#1960)
* `mlr reorder -r`

* fix

* update test/cases/cli-help/

* make dev
2026-02-14 19:40:20 -05:00
John Kerl
b8db798a2f
Miller 6.16.0 (#1930)
* Miller 6.16.0

* make dev
2026-01-02 13:57:59 -05:00
John Kerl
d0f824aefe
Run make dev after merge of PR 1868 (#1869) 2025-08-20 10:21:51 -07:00
John Kerl
3c2d4b22d2
Miller 6.15.0-dev (#1862)
* 6.15.0-dev

* make dev
2025-08-15 19:55:46 -04:00
John Kerl
8b524b3ada make dev 2025-08-15 19:48:48 -04:00
John Kerl
4ebef873d2
Miller 6.15.0 (#1860)
* miller 6.15.0

* make dev
2025-08-14 18:00:22 -04:00
John Kerl
fccdf215e6
DKVP --incr-key option (#1839)
* Code support for --incr-key

* Add source code for online help for new flag

* Run `make dev`
2025-07-20 17:05:24 -04:00
John Kerl
d264f562dc
Fix doc typo re empty and multiplication (#1838)
* Fix docs typo re empty and multiplication

* Run `make dev`
2025-07-20 16:36:50 -04:00
John Kerl
e7fe363d9a
mlr sort -b feature (#1833)
* `mlr sort -b` feature

* mlr regtest -p test/cases/cli-help && make dev
2025-07-11 12:41:04 -04:00
John Kerl
0ba6710a79 Update main version to 6.14.0-dev 2025-07-04 15:10:26 -04:00
John Kerl
7a6958926d
Miller 6.14.0 (#1828) 2025-07-04 13:55:56 -04:00
John Kerl
99a98b0dc7
Add -c, -t, -j to doc matrix in PR 1824 (#1826)
* Add `-c`, `-t`, `-j` to doc matrix in PR 1824

* Run `make dev`
2025-07-03 19:23:38 -04:00
Balki
d6cd981c87
Add Keystroke savers for same format (#1824) 2025-07-03 19:01:17 -04:00
Balki
e67bdef98e
cut: Consider -o flag even when using regexes with -r (#1823)
* cut: Consider `-o` flag even when using regexes with `-r`

* update doc for cut -r flag
2025-07-03 18:54:09 -04:00