feat: makes ls list all stores by default, with config option to disable. adds --store glob support

This commit is contained in:
Lewis Wynne 2026-02-11 23:04:14 +00:00
parent b6248e409f
commit 55b2e7f6cb
35 changed files with 487 additions and 177 deletions

View file

@ -2,7 +2,7 @@ $ pda set a1@ekf 1
$ pda set a2@ekf 2
$ pda set b1@ekf 3
$ pda export ekf --key "a*"
{"key":"a1","value":"1","encoding":"text"}
{"key":"a2","value":"2","encoding":"text"}
{"key":"a1","value":"1","encoding":"text","store":"ekf"}
{"key":"a2","value":"2","encoding":"text","store":"ekf"}
$ pda export ekf --key "c*" --> FAIL
FAIL cannot ls '@ekf': no matches for key pattern 'c*'

View file

@ -3,6 +3,6 @@ $ fecho tmpval hello world
$ pda set greeting@evf < tmpval
$ pda set number@evf 42
$ pda export evf --value "**https**"
{"key":"url","value":"https://example.com","encoding":"text"}
{"key":"url","value":"https://example.com","encoding":"text","store":"evf"}
$ pda export evf --value "**world**"
{"key":"greeting","value":"hello world\n","encoding":"text"}
{"key":"greeting","value":"hello world\n","encoding":"text","store":"evf"}

4
testdata/export.ct vendored
View file

@ -2,5 +2,5 @@
$ pda set a@exp 1
$ pda set b@exp 2
$ pda export exp
{"key":"a","value":"1","encoding":"text"}
{"key":"b","value":"2","encoding":"text"}
{"key":"a","value":"1","encoding":"text","store":"exp"}
{"key":"b","value":"2","encoding":"text","store":"exp"}

View file

@ -8,6 +8,7 @@ Usage:
Flags:
-h, --help help for export
-k, --key strings filter keys with glob pattern (repeatable)
-s, --store strings filter stores with glob pattern (repeatable)
-v, --value strings filter values with glob pattern (repeatable)
Export store as NDJSON (alias for list --format ndjson)
@ -17,4 +18,5 @@ Usage:
Flags:
-h, --help help for export
-k, --key strings filter keys with glob pattern (repeatable)
-s, --store strings filter stores with glob pattern (repeatable)
-v, --value strings filter values with glob pattern (repeatable)

View file

@ -6,19 +6,21 @@ Usage:
pda import [STORE] [flags]
Flags:
--drop drop existing entries before restoring (full replace)
-f, --file string path to an NDJSON dump (defaults to stdin)
-h, --help help for import
-i, --interactive prompt before overwriting existing keys
-k, --key strings restore keys matching glob pattern (repeatable)
--drop drop existing entries before restoring (full replace)
-f, --file string path to an NDJSON dump (defaults to stdin)
-h, --help help for import
-i, --interactive prompt before overwriting existing keys
-k, --key strings restore keys matching glob pattern (repeatable)
-s, --store strings restore entries from stores matching glob pattern (repeatable)
Restore key/value pairs from an NDJSON dump
Usage:
pda import [STORE] [flags]
Flags:
--drop drop existing entries before restoring (full replace)
-f, --file string path to an NDJSON dump (defaults to stdin)
-h, --help help for import
-i, --interactive prompt before overwriting existing keys
-k, --key strings restore keys matching glob pattern (repeatable)
--drop drop existing entries before restoring (full replace)
-f, --file string path to an NDJSON dump (defaults to stdin)
-h, --help help for import
-i, --interactive prompt before overwriting existing keys
-k, --key strings restore keys matching glob pattern (repeatable)
-s, --store strings restore entries from stores matching glob pattern (repeatable)

26
testdata/help-list.ct vendored
View file

@ -1,6 +1,15 @@
$ pda help list
$ pda list --help
List the contents of a store
List the contents of all stores.
By default, list shows entries from every store. Pass a store name as a
positional argument to narrow to a single store, or use --store/-s with a
glob pattern to filter by store name.
The Store column is always shown so entries can be distinguished across
stores. Use --key/-k and --value/-v to filter by key or value glob, and
--store/-s to filter by store name. All filters are repeatable and OR'd
within the same flag.
Usage:
pda list [STORE] [flags]
@ -9,6 +18,7 @@ Aliases:
list, ls
Flags:
-a, --all list across all stores
-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|json) (default table)
@ -19,8 +29,18 @@ Flags:
--no-keys suppress the key column
--no-ttl suppress the TTL column
--no-values suppress the value column
-s, --store strings filter stores with glob pattern (repeatable)
-v, --value strings filter values with glob pattern (repeatable)
List the contents of a store
List the contents of all stores.
By default, list shows entries from every store. Pass a store name as a
positional argument to narrow to a single store, or use --store/-s with a
glob pattern to filter by store name.
The Store column is always shown so entries can be distinguished across
stores. Use --key/-k and --value/-v to filter by key or value glob, and
--store/-s to filter by store name. All filters are repeatable and OR'd
within the same flag.
Usage:
pda list [STORE] [flags]
@ -29,6 +49,7 @@ Aliases:
list, ls
Flags:
-a, --all list across all stores
-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|json) (default table)
@ -39,4 +60,5 @@ Flags:
--no-keys suppress the key column
--no-ttl suppress the TTL column
--no-values suppress the value column
-s, --store strings filter stores with glob pattern (repeatable)
-v, --value strings filter values with glob pattern (repeatable)

View file

@ -9,10 +9,12 @@ Aliases:
remove, rm
Flags:
-h, --help help for remove
-i, --interactive prompt yes/no for each deletion
-k, --key strings delete keys matching glob pattern (repeatable)
-y, --yes skip all confirmation prompts
-h, --help help for remove
-i, --interactive prompt yes/no for each deletion
-k, --key strings delete keys matching glob pattern (repeatable)
-s, --store strings target stores matching glob pattern (repeatable)
-v, --value strings delete entries matching value glob pattern (repeatable)
-y, --yes skip all confirmation prompts
Delete one or more keys
Usage:
@ -22,7 +24,9 @@ Aliases:
remove, rm
Flags:
-h, --help help for remove
-i, --interactive prompt yes/no for each deletion
-k, --key strings delete keys matching glob pattern (repeatable)
-y, --yes skip all confirmation prompts
-h, --help help for remove
-i, --interactive prompt yes/no for each deletion
-k, --key strings delete keys matching glob pattern (repeatable)
-s, --store strings target stores matching glob pattern (repeatable)
-v, --value strings delete entries matching value glob pattern (repeatable)
-y, --yes skip all confirmation prompts

4
testdata/help.ct vendored
View file

@ -16,7 +16,7 @@ Key commands:
copy Make a copy of a key
get Get the value of a key
identity Show or create the age encryption identity
list List the contents of a store
list List the contents of all stores
move Move a key
remove Delete one or more keys
run Get the value of a key and execute it
@ -60,7 +60,7 @@ Key commands:
copy Make a copy of a key
get Get the value of a key
identity Show or create the age encryption identity
list List the contents of a store
list List the contents of all stores
move Move a key
remove Delete one or more keys
run Get the value of a key and execute it

29
testdata/list-all.ct vendored Normal file
View file

@ -0,0 +1,29 @@
# List defaults to all stores
$ pda set lax@laa 1
$ pda set lax@lab 2
$ pda ls --key "lax" --format tsv
Key Store Value TTL
lax laa 1 no expiry
lax lab 2 no expiry
$ pda ls --key "lax" --count
2
$ pda ls --key "lax" --format json
[{"key":"lax","value":"1","encoding":"text","store":"laa"},{"key":"lax","value":"2","encoding":"text","store":"lab"}]
# Positional arg narrows to one store
$ pda ls laa --key "lax" --format tsv
Key Store Value TTL
lax laa 1 no expiry
# --store glob filter
$ pda ls --store "la?" --key "lax" --format tsv
Key Store Value TTL
lax laa 1 no expiry
lax lab 2 no expiry
$ pda ls --store "laa" --key "lax" --format tsv
Key Store Value TTL
lax laa 1 no expiry
# --store cannot be combined with positional arg
$ pda ls --store "laa" laa --> FAIL
FAIL cannot use --store with a store argument
# --store no matches
$ pda ls --store "nonexistent" --key "lax" --> FAIL
FAIL cannot ls 'all': no matches for key pattern 'lax' and store pattern 'nonexistent'

View file

@ -2,6 +2,6 @@
$ pda set a@csv 1
$ pda set b@csv 2
$ pda ls csv --format csv
Key,Value,TTL
a,1,no expiry
b,2,no expiry
Key,Store,Value,TTL
a,csv,1,no expiry
b,csv,2,no expiry

View file

@ -2,4 +2,4 @@
$ 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"}]
[{"key":"a","value":"1","encoding":"text","store":"jf"},{"key":"b","value":"2","encoding":"text","store":"jf"}]

View file

@ -2,7 +2,7 @@
$ pda set a@md 1
$ pda set b@md 2
$ pda ls md --format markdown
| Key | Value | TTL |
| --- | --- | --- |
| a | 1 | no expiry |
| b | 2 | no expiry |
| Key | Store | Value | TTL |
| --- | --- | --- | --- |
| a | md | 1 | no expiry |
| b | md | 2 | no expiry |

View file

@ -2,5 +2,5 @@
$ pda set a@nj 1
$ pda set b@nj 2
$ pda ls nj --format ndjson
{"key":"a","value":"1","encoding":"text"}
{"key":"b","value":"2","encoding":"text"}
{"key":"a","value":"1","encoding":"text","store":"nj"}
{"key":"b","value":"2","encoding":"text","store":"nj"}

View file

@ -2,11 +2,11 @@ $ pda set a1@lg 1
$ pda set a2@lg 2
$ pda set b1@lg 3
$ pda ls lg --key "a*" --format tsv
Key Value TTL
a1 1 no expiry
a2 2 no expiry
Key Store Value TTL
a1 lg 1 no expiry
a2 lg 2 no expiry
$ pda ls lg --key "b*" --format tsv
Key Value TTL
b1 3 no expiry
Key Store Value TTL
b1 lg 3 no expiry
$ pda ls lg --key "c*" --> FAIL
FAIL cannot ls '@lg': no matches for key pattern 'c*'

View file

@ -2,10 +2,10 @@ $ pda set dburl@kv postgres://localhost:5432
$ pda set apiurl@kv https://api.example.com
$ pda set dbpass@kv s3cret
$ pda ls kv -k "db*" -v "**localhost**" --format tsv
Key Value TTL
dburl postgres://localhost:5432 no expiry
Key Store Value TTL
dburl kv postgres://localhost:5432 no expiry
$ pda ls kv -k "*url*" -v "**example**" --format tsv
Key Value TTL
apiurl https://api.example.com no expiry
Key Store Value TTL
apiurl kv https://api.example.com no expiry
$ pda ls kv -k "db*" -v "**nomatch**" --> FAIL
FAIL cannot ls '@kv': no matches for key pattern 'db*' and value pattern '**nomatch**'

View file

@ -1,4 +1,4 @@
# --no-header suppresses the header row
$ pda set a@nh 1
$ pda ls nh --format tsv --no-header
a 1 no expiry
a nh 1 no expiry

View file

@ -1,5 +1,5 @@
# --no-keys suppresses the key column
$ pda set a@nk 1
$ pda ls nk --format tsv --no-keys
Value TTL
1 no expiry
Store Value TTL
nk 1 no expiry

View file

@ -1,5 +1,5 @@
# --no-ttl suppresses the TTL column
$ pda set a@nt 1
$ pda ls nt --format tsv --no-ttl
Key Value
a 1
Key Store Value
a nt 1

View file

@ -1,5 +1,5 @@
# --no-values suppresses the value column
$ pda set a@nv 1
$ pda ls nv --format tsv --no-values
Key TTL
a no expiry
Key Store TTL
a nv no expiry

View file

@ -2,8 +2,8 @@
$ pda set a@lsalpha 1
$ pda set b@lsbeta 2
$ pda ls lsalpha --format tsv
Key Value TTL
a 1 no expiry
Key Store Value TTL
a lsalpha 1 no expiry
$ pda ls lsbeta --format tsv
Key Value TTL
b 2 no expiry
Key Store Value TTL
b lsbeta 2 no expiry

View file

@ -3,13 +3,13 @@ $ fecho tmpval hello world
$ pda set greeting@vt < tmpval
$ pda set number@vt 42
$ pda ls vt --value "**world**" --format tsv
Key Value TTL
greeting hello world (..1 more chars) no expiry
Key Store Value TTL
greeting vt hello world (..1 more chars) no expiry
$ pda ls vt --value "**https**" --format tsv
Key Value TTL
url https://example.com no expiry
Key Store Value TTL
url vt https://example.com no expiry
$ pda ls vt --value "*" --format tsv
Key Value TTL
number 42 no expiry
Key Store Value TTL
number vt 42 no expiry
$ pda ls vt --value "**nomatch**" --> FAIL
FAIL cannot ls '@vt': no matches for value pattern '**nomatch**'

View file

@ -3,6 +3,6 @@ $ fecho tmpval hello world
$ pda set greeting@vm < tmpval
$ pda set number@vm 42
$ pda ls vm --value "**world**" --value "42" --format tsv
Key Value TTL
greeting hello world (..1 more chars) no expiry
number 42 no expiry
Key Store Value TTL
greeting vm hello world (..1 more chars) no expiry
number vm 42 no expiry

View file

@ -6,5 +6,5 @@ bar
$ pda get x@ms2
y
$ pda ls ms2 --format tsv
Key Value TTL
x y no expiry
Key Store Value TTL
x ms2 y no expiry

View file

@ -2,10 +2,10 @@
$ pda set foo@rdd 1
$ pda set bar@rdd 2
$ pda ls rdd --format tsv
Key Value TTL
bar 2 no expiry
foo 1 no expiry
$ pda rm foo@rdd --key "*@rdd"
Key Store Value TTL
bar rdd 2 no expiry
foo rdd 1 no expiry
$ pda rm foo@rdd --key "*@rdd" -y
$ pda get bar@rdd --> FAIL
FAIL cannot get 'bar@rdd': no such key
$ pda get foo@rdd --> FAIL

View file

@ -1,7 +1,7 @@
$ pda set a1@rkg 1
$ pda set a2@rkg 2
$ pda set b1@rkg 3
$ pda rm --key "a*@rkg"
$ pda rm --key "a*@rkg" -y
$ pda get a1@rkg --> FAIL
FAIL cannot get 'a1@rkg': no such key
hint did you mean 'b1'?

View file

@ -1,7 +1,7 @@
$ pda set foo@rkm 1
$ pda set bar1@rkm 2
$ pda set bar2@rkm 3
$ pda rm foo@rkm --key "bar*@rkm"
$ pda rm foo@rkm --key "bar*@rkm" -y
$ pda get foo@rkm --> FAIL
FAIL cannot get 'foo@rkm': no such key
$ pda get bar1@rkm --> FAIL

2
testdata/root.ct vendored
View file

@ -15,7 +15,7 @@ Key commands:
copy Make a copy of a key
get Get the value of a key
identity Show or create the age encryption identity
list List the contents of a store
list List the contents of all stores
move Move a key
remove Delete one or more keys
run Get the value of a key and execute it