commit 3a20266324068de66972ca077bc95b35d92e6443
parent 75f9685e2706574beb471606eb40bcb7c9cb022e
Author: Sean Enck <sean@ttypty.com>
Date: Thu, 30 Mar 2023 20:44:09 -0400
better output handling for json dumps
Diffstat:
8 files changed, 66 insertions(+), 60 deletions(-)
diff --git a/internal/app/conv.go b/internal/app/conv.go
@@ -1,6 +1,8 @@
package app
import (
+ "bytes"
+ "encoding/json"
"errors"
"fmt"
"io"
@@ -32,13 +34,17 @@ func serialize(w io.Writer, tx *backend.Transaction) error {
if err != nil {
return err
}
- fmt.Fprintf(w, "[")
+ fmt.Fprint(w, "{\n")
for idx, item := range e {
if idx > 0 {
- fmt.Fprint(w, ",")
+ fmt.Fprintf(w, ",\n")
}
- fmt.Fprintf(w, "\n%s\n", item.Value)
+ var buf bytes.Buffer
+ if err := json.Indent(&buf, []byte(item.Value), " ", " "); err != nil {
+ return err
+ }
+ fmt.Fprintf(w, " \"%s\": %s\n", item.Path, buf.String())
}
- fmt.Fprintf(w, "]")
+ fmt.Fprintf(w, "}")
return nil
}
diff --git a/internal/app/json.go b/internal/app/json.go
@@ -2,6 +2,8 @@
package app
import (
+ "bytes"
+ "encoding/json"
"errors"
"fmt"
@@ -23,7 +25,11 @@ func JSON(cmd CommandOptions) error {
return fmt.Errorf("unable to get json: %w", err)
}
if v != nil {
- fmt.Fprintln(cmd.Writer(), v.Value)
+ var buf bytes.Buffer
+ if err := json.Indent(&buf, []byte(v.Value), "", " "); err != nil {
+ return err
+ }
+ fmt.Fprintln(cmd.Writer(), buf.String())
}
return nil
}
diff --git a/internal/app/rekey.go b/internal/app/rekey.go
@@ -17,7 +17,7 @@ import (
type (
// Keyer defines how rekeying happens
Keyer interface {
- JSON() ([]backend.JSON, error)
+ JSON() (map[string]backend.JSON, error)
Show(string) ([]byte, error)
Insert(ReKeyEntry) error
}
@@ -48,12 +48,12 @@ func (r DefaultKeyer) Show(entry string) ([]byte, error) {
}
// JSON will get the JSON backing entries
-func (r DefaultKeyer) JSON() ([]backend.JSON, error) {
+func (r DefaultKeyer) JSON() (map[string]backend.JSON, error) {
out, err := exec.Command(r.exe, cli.JSONCommand).Output()
if err != nil {
return nil, err
}
- var j []backend.JSON
+ var j map[string]backend.JSON
if err := json.Unmarshal(out, &j); err != nil {
return nil, err
}
@@ -87,22 +87,22 @@ func ReKey(writer io.Writer, r Keyer) error {
if err != nil {
return err
}
- for _, entry := range entries {
- if _, err := fmt.Fprintf(writer, "rekeying: %s\n", entry.Path); err != nil {
+ for path, entry := range entries {
+ if _, err := fmt.Fprintf(writer, "rekeying: %s\n", path); err != nil {
return err
}
modTime := strings.TrimSpace(entry.ModTime)
if modTime == "" {
return errors.New("did not read modtime")
}
- data, err := r.Show(entry.Path)
+ data, err := r.Show(path)
if err != nil {
return err
}
var insertEnv []string
insertEnv = append(insertEnv, env...)
insertEnv = append(insertEnv, fmt.Sprintf("%s=%s", inputs.ModTimeEnv, modTime))
- if err := r.Insert(ReKeyEntry{Path: entry.Path, Env: insertEnv, Data: data}); err != nil {
+ if err := r.Insert(ReKeyEntry{Path: path, Env: insertEnv, Data: data}); err != nil {
return err
}
}
diff --git a/internal/app/rekey_test.go b/internal/app/rekey_test.go
@@ -16,11 +16,11 @@ type (
data map[string][]byte
err error
rekeys []app.ReKeyEntry
- items []backend.JSON
+ items map[string]backend.JSON
}
)
-func (m *mockKeyer) JSON() ([]backend.JSON, error) {
+func (m *mockKeyer) JSON() (map[string]backend.JSON, error) {
if m.err != nil {
return nil, m.err
}
@@ -57,18 +57,18 @@ func TestErrors(t *testing.T) {
t.Errorf("invalid error: %v", err)
}
m.err = nil
- m.items = []backend.JSON{{Path: "test1", ModTime: ""}}
+ m.items = map[string]backend.JSON{"test": {ModTime: ""}}
if err := app.ReKey(&buf, m); err == nil || err.Error() != "did not read modtime" {
t.Errorf("invalid error: %v", err)
}
- m.items = []backend.JSON{{Path: "test1", ModTime: "2"}}
+ m.items = map[string]backend.JSON{"test1": {ModTime: "2"}}
if err := app.ReKey(&buf, m); err == nil || err.Error() != "no data" {
t.Errorf("invalid error: %v", err)
}
m.data = make(map[string][]byte)
m.data["test1"] = []byte{1}
m.data["error"] = []byte{2}
- m.items = []backend.JSON{{Path: "error", ModTime: "2"}}
+ m.items = map[string]backend.JSON{"error": {ModTime: "2"}}
if err := app.ReKey(&buf, m); err == nil || err.Error() != "bad insert" {
t.Errorf("invalid error: %v", err)
}
@@ -84,7 +84,10 @@ func TestReKey(t *testing.T) {
t.Error("no data")
}
m := &mockKeyer{}
- m.items = []backend.JSON{{Path: "test1", ModTime: "2"}, {Path: "test1", ModTime: "2"}}
+ m.items = map[string]backend.JSON{
+ "test1": {ModTime: "1"},
+ "test2": {ModTime: "2"},
+ }
m.data = make(map[string][]byte)
m.data["test1"] = []byte{1}
m.data["test2"] = []byte{2}
@@ -97,7 +100,7 @@ func TestReKey(t *testing.T) {
if len(m.rekeys) != 2 {
t.Error("invalid rekeys")
}
- if fmt.Sprintf("%v", m.rekeys) != `[{test1 [LOCKBOX_KEYMODE= LOCKBOX_KEY=abc LOCKBOX_KEYFILE= LOCKBOX_STORE=store LOCKBOX_SET_MODTIME=2] [1]} {test1 [LOCKBOX_KEYMODE= LOCKBOX_KEY=abc LOCKBOX_KEYFILE= LOCKBOX_STORE=store LOCKBOX_SET_MODTIME=2] [1]}]` {
+ if fmt.Sprintf("%v", m.rekeys) != `[{test1 [LOCKBOX_KEYMODE= LOCKBOX_KEY=abc LOCKBOX_KEYFILE= LOCKBOX_STORE=store LOCKBOX_SET_MODTIME=1] [1]} {test2 [LOCKBOX_KEYMODE= LOCKBOX_KEY=abc LOCKBOX_KEYFILE= LOCKBOX_STORE=store LOCKBOX_SET_MODTIME=2] [2]}]` {
t.Errorf("invalid results: %v", m.rekeys)
}
}
diff --git a/internal/backend/query.go b/internal/backend/query.go
@@ -132,8 +132,8 @@ func (t *Transaction) QueryCallback(args QueryOptions) ([]QueryEntity, error) {
switch args.Values {
case JSONValue:
t := getValue(e.backing, modTimeKey)
- s := JSON{Path: k, ModTime: t, Hash: fmt.Sprintf("%x", sha512.Sum512([]byte(val)))}
- m, err := json.MarshalIndent(s, "", " ")
+ s := JSON{ModTime: t, Hash: fmt.Sprintf("%x", sha512.Sum512([]byte(val)))}
+ m, err := json.Marshal(s)
if err != nil {
return nil, err
}
diff --git a/internal/backend/query_test.go b/internal/backend/query_test.go
@@ -111,7 +111,7 @@ func TestValueModes(t *testing.T) {
if err := json.Unmarshal([]byte(q.Value), &m); err != nil {
t.Errorf("no error: %v", err)
}
- if len(m.ModTime) < 20 || m.Path != "test/test/abc" {
+ if len(m.ModTime) < 20 || m.Hash == "" {
t.Errorf("invalid json: %v", m)
}
}
diff --git a/internal/backend/types.go b/internal/backend/types.go
@@ -55,7 +55,6 @@ type (
}
// JSON is an entry as a JSON string
JSON struct {
- Path string `json:"path"`
ModTime string `json:"modtime"`
Hash string `json:"hash"`
}
diff --git a/tests/expected.log b/tests/expected.log
@@ -12,30 +12,26 @@ keys2/k/three
key/a/one
keys/k/one2
keys2/k/three
-[
{
- "path": "key/a/one",
- "modtime": "XXXX-XX-XX",
- "hash": "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff"
-}
+ "key/a/one": {
+ "modtime": "XXXX-XX-XX",
+ "hash": "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff"
+ }
,
-{
- "path": "keys/k/one2",
- "modtime": "XXXX-XX-XX",
- "hash": "6d201beeefb589b08ef0672dac82353d0cbd9ad99e1642c83a1601f3d647bcca003257b5e8f31bdc1d73fbec84fb085c79d6e2677b7ff927e823a54e789140d9"
-}
+ "keys/k/one2": {
+ "modtime": "XXXX-XX-XX",
+ "hash": "6d201beeefb589b08ef0672dac82353d0cbd9ad99e1642c83a1601f3d647bcca003257b5e8f31bdc1d73fbec84fb085c79d6e2677b7ff927e823a54e789140d9"
+ }
,
-{
- "path": "keys2/k/three",
- "modtime": "XXXX-XX-XX",
- "hash": "132ab0244293c495a027cec12d0050598616daca888449920fc652719be0987830827d069ef78cc613e348de37c9b592d3406e2fb8d99a6961bf0c58da8a334f"
+ "keys2/k/three": {
+ "modtime": "XXXX-XX-XX",
+ "hash": "132ab0244293c495a027cec12d0050598616daca888449920fc652719be0987830827d069ef78cc613e348de37c9b592d3406e2fb8d99a6961bf0c58da8a334f"
+ }
}
-]
test2
test3
test4
{
- "path": "keys2/k/three",
"modtime": "XXXX-XX-XX",
"hash": "132ab0244293c495a027cec12d0050598616daca888449920fc652719be0987830827d069ef78cc613e348de37c9b592d3406e2fb8d99a6961bf0c58da8a334f"
}
@@ -44,31 +40,27 @@ test/k
XXXXXX
XXXXXX
XXXXXX
-[
{
- "path": "key/a/one",
- "modtime": "XXXX-XX-XX",
- "hash": "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff"
-}
+ "key/a/one": {
+ "modtime": "XXXX-XX-XX",
+ "hash": "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff"
+ }
,
-{
- "path": "keys/k/one2",
- "modtime": "XXXX-XX-XX",
- "hash": "6d201beeefb589b08ef0672dac82353d0cbd9ad99e1642c83a1601f3d647bcca003257b5e8f31bdc1d73fbec84fb085c79d6e2677b7ff927e823a54e789140d9"
-}
+ "keys/k/one2": {
+ "modtime": "XXXX-XX-XX",
+ "hash": "6d201beeefb589b08ef0672dac82353d0cbd9ad99e1642c83a1601f3d647bcca003257b5e8f31bdc1d73fbec84fb085c79d6e2677b7ff927e823a54e789140d9"
+ }
,
-{
- "path": "keys2/k/three",
- "modtime": "XXXX-XX-XX",
- "hash": "132ab0244293c495a027cec12d0050598616daca888449920fc652719be0987830827d069ef78cc613e348de37c9b592d3406e2fb8d99a6961bf0c58da8a334f"
-}
+ "keys2/k/three": {
+ "modtime": "XXXX-XX-XX",
+ "hash": "132ab0244293c495a027cec12d0050598616daca888449920fc652719be0987830827d069ef78cc613e348de37c9b592d3406e2fb8d99a6961bf0c58da8a334f"
+ }
,
-{
- "path": "test/k/totp",
- "modtime": "XXXX-XX-XX",
- "hash": "7ef183065ba70aaa417b87ea0a96b7e550a938a52440c640a07537f7794d8a89e50078eca6a7cbcfacabd97a2db06d11e82ddf7556ca909c4df9fc0d006013b1"
-}
-]delete entry? (y/N)
+ "test/k/totp": {
+ "modtime": "XXXX-XX-XX",
+ "hash": "7ef183065ba70aaa417b87ea0a96b7e550a938a52440c640a07537f7794d8a89e50078eca6a7cbcfacabd97a2db06d11e82ddf7556ca909c4df9fc0d006013b1"
+ }
+}delete entry? (y/N)
delete entry? (y/N)
delete entry? (y/N) unable to remove: no entities given