Skip to content

Commit 59b4d2d

Browse files
authored
Keyvalue store any (#30)
key-value item, allow to store any
1 parent 7eb1425 commit 59b4d2d

File tree

4 files changed

+106
-1
lines changed

4 files changed

+106
-1
lines changed

README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,75 @@ launchr login \
2727
--keyring-passphrase-file=/path/to/your/secret
2828
```
2929

30+
To add a new key-value pair with an interactive shell:
31+
```shell
32+
launchr keyring:set your-key
33+
```
34+
35+
It's possible to parse a user value and store it as a struct in a keyring. Supported formats are [string, yaml, json]:
36+
```shell
37+
launchr keyring:set your-key value
38+
```
39+
40+
It's possible to parse a user value and store it as a struct in a keyring. Possible formats are [string, yaml, json]:
41+
```shell
42+
launchr keyring:set key --format yaml -- "- name: test-1
43+
- name: test-2"
44+
launchr keyring:set key --format yaml -- "$(cat file.yaml)"
45+
launchr keyring:set key --format json -- '[
46+
{
47+
"name": "test-1"
48+
},
49+
{
50+
"name": "test-2"
51+
}
52+
]'
53+
launchr keyring:set key --format json -- "$(cat file.json)"
54+
```
55+
56+
You can dynamically build JSON\YAML wit structures and pass them directly to the command: `jq`
57+
```shell
58+
# Define your variables
59+
TOKEN1="abc123def456"
60+
NAME1="production-api-key"
61+
CREATED1="2025-01-15T10:30:00Z"
62+
63+
TOKEN2="xyz789uvw012"
64+
NAME2="development-token"
65+
CREATED2="2025-01-15T11:45:00Z"
66+
EXPIRES2="2025-07-15T11:45:00Z"
67+
68+
launchr keyring:set api-tokens-json --format json -- "$(jq -n \
69+
--arg t1 "$TOKEN1" --arg n1 "$NAME1" --arg c1 "$CREATED1" \
70+
--arg t2 "$TOKEN2" --arg n2 "$NAME2" --arg c2 "$CREATED2" --arg e2 "$EXPIRES2" \
71+
'[
72+
{
73+
tokenhash: $t1,
74+
name: $n1,
75+
created: $c1,
76+
expires: null
77+
},
78+
{
79+
tokenhash: $t2,
80+
name: $n2,
81+
created: $c2,
82+
expires: $e2
83+
}
84+
]')"
85+
```
86+
`yq` using same variables:
87+
```shell
88+
launchr keyring:set api-tokens-yaml --format yaml -- "$(yq -n \
89+
'.[0].tokenhash = env(TOKEN1) |
90+
.[0].name = env(NAME1) |
91+
.[0].created = env(CREATED1) |
92+
.[0].expires = null |
93+
.[1].tokenhash = env(TOKEN2) |
94+
.[1].name = env(NAME2) |
95+
.[1].created = env(CREATED2) |
96+
.[1].expires = env(EXPIRES2)')"
97+
```
98+
3099
Flags `--keyring-passphrase` and `--keyring-passphrase-file` are available for all launchr commands, for example:
31100
```shell
32101
launchr compose --keyring-passphrase=YOURPASSHRPASE

action.set.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,9 @@ action:
1313
title: Value
1414
description: Value
1515
default: ""
16+
options:
17+
- name: format
18+
title: Value Format
19+
description: Format to parse the input value
20+
enum: ["string", "yaml", "json"]
21+
default: string

plugin.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,17 @@ func (p *Plugin) DiscoverActions(_ context.Context) ([]*action.Action, error) {
175175
key := KeyValueItem{
176176
Key: input.Arg("key").(string),
177177
}
178-
key.Value, _ = input.Arg("value").(string)
178+
179+
userValue := input.Arg("value").(string)
180+
format := input.Opt("format").(string)
181+
var err error
182+
183+
// @TODO cover with tests
184+
key.Value, err = parseFromString(format, userValue)
185+
if err != nil {
186+
return fmt.Errorf("failed to parse %s: %w", format, err)
187+
}
188+
179189
return saveKey(p.k, key)
180190
}))
181191

yaml.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package keyring
22

33
import (
4+
"encoding/json"
45
"errors"
56
"os"
67
"strings"
@@ -235,3 +236,22 @@ func (s *dataStoreYaml) Save() error {
235236
func (s *dataStoreYaml) Destroy() error {
236237
return s.file.Remove()
237238
}
239+
240+
func parseFromString(format, value string) (interface{}, error) {
241+
if format == "string" || value == "" {
242+
return value, nil
243+
}
244+
245+
var parsed interface{}
246+
var err error
247+
switch format {
248+
case "json":
249+
err = json.Unmarshal([]byte(value), &parsed)
250+
case "yaml":
251+
err = yaml.Unmarshal([]byte(value), &parsed)
252+
default:
253+
panic("unsupported format: " + format)
254+
}
255+
256+
return parsed, err
257+
}

0 commit comments

Comments
 (0)