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 --> <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 --> <p align="center"></p><!-- spacer -->
@ -229,7 +229,11 @@ pda ls --format csv
# name,Alice,no expiry # name,Alice,no expiry
# dogs,four legged mammals,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. # Just the count of entries.
pda ls --count pda ls --count

View file

@ -46,11 +46,11 @@ func (e *formatEnum) String() string { return string(*e) }
func (e *formatEnum) Set(v string) error { func (e *formatEnum) Set(v string) error {
switch v { switch v {
case "table", "tsv", "csv", "html", "markdown", "ndjson": case "table", "tsv", "csv", "html", "markdown", "ndjson", "json":
*e = formatEnum(v) *e = formatEnum(v)
return nil return nil
default: 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 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 // Table-based formats
showValues := !listNoValues showValues := !listNoValues
tw := table.NewWriter() tw := table.NewWriter()
@ -485,7 +503,7 @@ func init() {
listCmd.Flags().BoolVar(&listNoTTL, "no-ttl", false, "suppress the TTL column") 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().BoolVarP(&listFull, "full", "f", false, "show full values without truncation")
listCmd.Flags().BoolVar(&listNoHeader, "no-header", false, "suppress the header row") 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("key", "k", nil, "filter keys with glob pattern (repeatable)")
listCmd.Flags().StringSliceP("value", "v", nil, "filter values with glob pattern (repeatable)") listCmd.Flags().StringSliceP("value", "v", nil, "filter values with glob pattern (repeatable)")
rootCmd.AddCommand(listCmd) rootCmd.AddCommand(listCmd)

View file

@ -11,7 +11,7 @@ Aliases:
Flags: Flags:
-b, --base64 view binary data as base64 -b, --base64 view binary data as base64
-c, --count print only the count of matching entries -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 -f, --full show full values without truncation
-h, --help help for list -h, --help help for list
-k, --key strings filter keys with glob pattern (repeatable) -k, --key strings filter keys with glob pattern (repeatable)
@ -31,7 +31,7 @@ Aliases:
Flags: Flags:
-b, --base64 view binary data as base64 -b, --base64 view binary data as base64
-c, --count print only the count of matching entries -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 -f, --full show full values without truncation
-h, --help help for list -h, --help help for list
-k, --key strings filter keys with glob pattern (repeatable) -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"}]