1
1
package dsl
2
2
3
3
import (
4
+ "bytes"
4
5
"context"
6
+ "io"
7
+ "os"
8
+ "path/filepath"
5
9
6
10
"github.com/pkg/errors"
7
11
"github.com/vim-volt/volt/dsl/dslctx"
8
12
"github.com/vim-volt/volt/dsl/types"
13
+ "github.com/vim-volt/volt/pathutil"
9
14
"github.com/vim-volt/volt/transaction"
10
15
)
11
16
@@ -26,10 +31,77 @@ func Execute(ctx context.Context, expr types.Expr) (_ types.Value, result error)
26
31
}
27
32
}()
28
33
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
+
29
46
val , rollback , err := expr .Eval (ctx )
30
47
if err != nil {
31
48
rollback ()
32
49
return nil , errors .Wrap (err , "expression returned an error" )
33
50
}
34
51
return val , nil
35
52
}
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