Skip to content

Commit 9ae163f

Browse files
committed
feat: write transaction log before evaluation
1 parent 11007bb commit 9ae163f

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

dsl/deparse.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010

1111
// Deparse deparses types.Expr.
1212
// ["@", 1, 2, 3] becomes [1, 2, 3]
13-
func Deparse(expr types.Expr) (interface{}, error) {
13+
func Deparse(expr types.Expr) ([]byte, error) {
1414
value, err := deparse(expr)
1515
if err != nil {
1616
return nil, err

dsl/execute.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package dsl
22

33
import (
4+
"bytes"
45
"context"
6+
"io"
7+
"os"
8+
"path/filepath"
59

610
"github.com/pkg/errors"
711
"github.com/vim-volt/volt/dsl/dslctx"
812
"github.com/vim-volt/volt/dsl/types"
13+
"github.com/vim-volt/volt/pathutil"
914
"github.com/vim-volt/volt/transaction"
1015
)
1116

@@ -26,10 +31,77 @@ func Execute(ctx context.Context, expr types.Expr) (_ types.Value, result error)
2631
}
2732
}()
2833

34+
// Expand all macros before write
35+
expr, err = expandMacro(expr)
36+
if err != nil {
37+
return nil, errors.Wrap(err, "failed to expand macros")
38+
}
39+
40+
// Write given expression to $VOLTPATH/trx/lock/log.json
41+
err = writeExpr(expr)
42+
if err != nil {
43+
return nil, err
44+
}
45+
2946
val, rollback, err := expr.Eval(ctx)
3047
if err != nil {
3148
rollback()
3249
return nil, errors.Wrap(err, "expression returned an error")
3350
}
3451
return val, nil
3552
}
53+
54+
func expandMacro(expr types.Expr) (types.Expr, error) {
55+
val, err := doExpandMacro(expr)
56+
if err != nil {
57+
return nil, err
58+
}
59+
result, ok := val.(types.Expr)
60+
if !ok {
61+
return nil, errors.New("the result of expansion of macros must be an expression")
62+
}
63+
return result, nil
64+
}
65+
66+
func writeExpr(expr types.Expr) error {
67+
deparsed, err := Deparse(expr)
68+
if err != nil {
69+
return errors.Wrap(err, "failed to deparse expression")
70+
}
71+
72+
filename := filepath.Join(pathutil.TrxDir(), "lock", "log.json")
73+
logFile, err := os.Create(filename)
74+
if err != nil {
75+
return errors.Wrapf(err, "could not create %s", filename)
76+
}
77+
_, err = io.Copy(logFile, bytes.NewReader(deparsed))
78+
if err != nil {
79+
return errors.Wrapf(err, "failed to write transaction log %s", filename)
80+
}
81+
err = logFile.Close()
82+
if err != nil {
83+
return errors.Wrapf(err, "failed to close transaction log %s", filename)
84+
}
85+
return nil
86+
}
87+
88+
// doExpandMacro expands macro's expression recursively
89+
func doExpandMacro(expr types.Expr) (types.Value, error) {
90+
op := expr.Op()
91+
if !op.IsMacro() {
92+
return expr, nil
93+
}
94+
args := expr.Args()
95+
for i := range args {
96+
if inner, ok := args[i].(types.Expr); ok {
97+
v, err := doExpandMacro(inner)
98+
if err != nil {
99+
return nil, err
100+
}
101+
args[i] = v
102+
}
103+
}
104+
// XXX: should we care rollback function?
105+
val, _, err := op.EvalExpr(context.Background(), args)
106+
return val, err
107+
}

0 commit comments

Comments
 (0)