-
-
Notifications
You must be signed in to change notification settings - Fork 33
/
dump.go
122 lines (114 loc) · 2.39 KB
/
dump.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package runn
import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"reflect"
"github.com/goccy/go-json"
"github.com/k1LoW/donegroup"
)
const dumpRunnerKey = "dump"
type dumpRunner struct{}
type dumpRequest struct {
expr string
out string
disableTrailingNewline bool
disableMaskingSecrets bool
}
func newDumpRunner() *dumpRunner {
return &dumpRunner{}
}
func (rnr *dumpRunner) Run(ctx context.Context, s *step, first bool) error {
r := s.dumpRequest
o := s.parent
var out io.Writer
store := o.store.toMap()
store[storeRootKeyIncluded] = o.included
if first {
store[storeRootKeyPrevious] = o.store.latest()
} else {
store[storeRootKeyPrevious] = o.store.previous()
store[storeRootKeyCurrent] = o.store.latest()
}
if r.out == "" {
if r.disableMaskingSecrets {
out = o.stdout.Unwrap()
} else {
out = o.stdout
}
} else {
p, err := EvalExpand(r.out, store)
if err != nil {
return err
}
switch pp := p.(type) {
case string:
if !filepath.IsAbs(pp) {
pp = filepath.Join(filepath.Dir(o.bookPath), pp)
}
f, err := os.Create(pp)
if err != nil {
return err
}
if err := donegroup.Cleanup(ctx, func() error {
return f.Close()
}); err != nil {
return err
}
if r.disableMaskingSecrets {
out = f
} else {
out = o.maskRule.NewWriter(f)
}
default:
return fmt.Errorf("invalid dump out: %v", pp)
}
}
v, err := Eval(r.expr, store)
if err != nil {
return err
}
if err := rnr.run(ctx, out, v, r.disableTrailingNewline, s, first); err != nil {
return fmt.Errorf("failed to run dump: %w", err)
}
return nil
}
func (rnr *dumpRunner) run(_ context.Context, out io.Writer, v any, disableNL bool, s *step, first bool) error {
o := s.parent
switch vv := v.(type) {
case string:
if _, err := fmt.Fprint(out, vv); err != nil {
return err
}
case []byte:
// e.g. screenshot on CDP
if _, err := out.Write(vv); err != nil {
return err
}
default:
if reflect.ValueOf(v).Kind() == reflect.Func {
if _, err := fmt.Fprint(out, storeFuncValue); err != nil {
return err
}
} else {
b, err := json.MarshalIndent(v, "", " ")
if err != nil {
return err
}
if _, err := fmt.Fprint(out, string(b)); err != nil {
return err
}
}
}
if !disableNL {
if _, err := fmt.Fprint(out, "\n"); err != nil {
return err
}
}
if first {
o.record(nil)
}
return nil
}