feat(list): adds plain json formatting

This commit is contained in:
Lewis Wynne 2026-02-11 19:34:29 +00:00
parent 15c1d6733c
commit ce7336324f
4 changed files with 34 additions and 7 deletions

View file

@ -31,7 +31,7 @@ and more, written in pure Go, and inspired by [skate](https://github.com/charmbr
<p align="center"></p><!-- spacer -->
`pda!` stores key-value pairs natively as [newline-delimited JSON](https://en.wikipedia.org/wiki/JSON_streaming#Newline-delimited_JSON) files. The `list` command outputs tabular data by default, but also supports [CSV](https://en.wikipedia.org/wiki/Comma-separated_values), [TSV](https://en.wikipedia.org/wiki/Tab-separated_values), [Markdown](https://en.wikipedia.org/wiki/Markdown) and [HTML](https://en.wikipedia.org/wiki/HTML_element#Tables) tables, and raw NDJSON. Because every store is in plaintext, Git versioning is pretty easy: auto-committing, pushing, and fetching can be enabled in the config to automatically version changes, or just `pda sync` regularly.
`pda!` stores key-value pairs natively as [newline-delimited JSON](https://en.wikipedia.org/wiki/JSON_streaming#Newline-delimited_JSON) files. The `list` command outputs tabular data by default, but also supports [CSV](https://en.wikipedia.org/wiki/Comma-separated_values), [TSV](https://en.wikipedia.org/wiki/Tab-separated_values), [Markdown](https://en.wikipedia.org/wiki/Markdown) and [HTML](https://en.wikipedia.org/wiki/HTML_element#Tables) tables, JSON, and raw NDJSON. Because every store is in plaintext, Git versioning is pretty easy: auto-committing, pushing, and fetching can be enabled in the config to automatically version changes, or just `pda sync` regularly.
<p align="center"></p><!-- spacer -->
@ -229,7 +229,11 @@ pda ls --format csv
# name,Alice,no expiry
# dogs,four legged mammals,no expiry
# Or TSV, or Markdown, or HTML.
# Or as a JSON array.
pda ls --format json
# [{"key":"name","value":"Alice","encoding":"text"},{"key":"dogs","value":"four legged mammals","encoding":"text"}]
# Or TSV, Markdown, HTML, NDJSON.
# Just the count of entries.
pda ls --count

View file

@ -46,11 +46,11 @@ func (e *formatEnum) String() string { return string(*e) }
func (e *formatEnum) Set(v string) error {
switch v {
case "table", "tsv", "csv", "html", "markdown", "ndjson":
case "table", "tsv", "csv", "html", "markdown", "ndjson", "json":
*e = formatEnum(v)
return nil
default:
return fmt.Errorf("must be one of 'table', 'tsv', 'csv', 'html', 'markdown', or 'ndjson'")
return fmt.Errorf("must be one of 'table', 'tsv', 'csv', 'html', 'markdown', 'ndjson', or 'json'")
}
}
@ -196,6 +196,24 @@ func list(cmd *cobra.Command, args []string) error {
return nil
}
// JSON format: emit a single JSON array
if listFormat.String() == "json" {
var entries []jsonEntry
for _, e := range filtered {
je, err := encodeJsonEntry(e, recipient)
if err != nil {
return fmt.Errorf("cannot ls '%s': %v", targetDB, err)
}
entries = append(entries, je)
}
data, err := json.Marshal(entries)
if err != nil {
return fmt.Errorf("cannot ls '%s': %v", targetDB, err)
}
fmt.Fprintln(output, string(data))
return nil
}
// Table-based formats
showValues := !listNoValues
tw := table.NewWriter()
@ -485,7 +503,7 @@ func init() {
listCmd.Flags().BoolVar(&listNoTTL, "no-ttl", false, "suppress the TTL column")
listCmd.Flags().BoolVarP(&listFull, "full", "f", false, "show full values without truncation")
listCmd.Flags().BoolVar(&listNoHeader, "no-header", false, "suppress the header row")
listCmd.Flags().VarP(&listFormat, "format", "o", "output format (table|tsv|csv|markdown|html|ndjson)")
listCmd.Flags().VarP(&listFormat, "format", "o", "output format (table|tsv|csv|markdown|html|ndjson|json)")
listCmd.Flags().StringSliceP("key", "k", nil, "filter keys with glob pattern (repeatable)")
listCmd.Flags().StringSliceP("value", "v", nil, "filter values with glob pattern (repeatable)")
rootCmd.AddCommand(listCmd)

View file

@ -11,7 +11,7 @@ Aliases:
Flags:
-b, --base64 view binary data as base64
-c, --count print only the count of matching entries
-o, --format format output format (table|tsv|csv|markdown|html|ndjson) (default table)
-o, --format format output format (table|tsv|csv|markdown|html|ndjson|json) (default table)
-f, --full show full values without truncation
-h, --help help for list
-k, --key strings filter keys with glob pattern (repeatable)
@ -31,7 +31,7 @@ Aliases:
Flags:
-b, --base64 view binary data as base64
-c, --count print only the count of matching entries
-o, --format format output format (table|tsv|csv|markdown|html|ndjson) (default table)
-o, --format format output format (table|tsv|csv|markdown|html|ndjson|json) (default table)
-f, --full show full values without truncation
-h, --help help for list
-k, --key strings filter keys with glob pattern (repeatable)

5
testdata/list-format-json.ct vendored Normal file
View file

@ -0,0 +1,5 @@
# JSON array format output via list
$ pda set a@jf 1
$ pda set b@jf 2
$ pda ls jf --format json
[{"key":"a","value":"1","encoding":"text"},{"key":"b","value":"2","encoding":"text"}]