Skip to content

Commit de29bd2

Browse files
committed
Add interactive mode, fixes and improvements
1 parent bbc873f commit de29bd2

30 files changed

+817
-132
lines changed

execution/execute.go

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -135,30 +135,9 @@ func exprExecutor(opts *Options, expr ast.Expr) (expressionExecutor, error) {
135135
func chainedExprExecutor(options *Options, e ast.ChainedExpr) (expressionExecutor, error) {
136136
return func(data *model.Value) (*model.Value, error) {
137137
for _, expr := range e.Exprs {
138-
139-
if !data.IsBranch() {
140-
res, err := ExecuteAST(expr, data, options)
141-
if err != nil {
142-
return nil, fmt.Errorf("error executing expression: %w", err)
143-
}
144-
data = res
145-
continue
146-
}
147-
148-
res := model.NewSliceValue()
149-
res.MarkAsBranch()
150-
if err := data.RangeSlice(func(i int, value *model.Value) error {
151-
r, err := ExecuteAST(expr, value, options)
152-
if err != nil {
153-
return fmt.Errorf("error executing expression: %w", err)
154-
}
155-
156-
if err := res.Append(r); err != nil {
157-
return err
158-
}
159-
return nil
160-
}); err != nil {
161-
return nil, err
138+
res, err := ExecuteAST(expr, data, options)
139+
if err != nil {
140+
return nil, fmt.Errorf("error executing expression: %w", err)
162141
}
163142
data = res
164143
}

execution/execute_binary.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ func basicBinaryExpressionExecutorFn(handler func(left *model.Value, right *mode
2323
if err != nil {
2424
return nil, fmt.Errorf("error evaluating right expression: %w", err)
2525
}
26-
return handler(left, right, expr)
26+
res, err := handler(left, right, expr)
27+
if err != nil {
28+
return nil, err
29+
}
30+
return res, nil
2731
}
2832

2933
res := model.NewSliceValue()
@@ -52,6 +56,9 @@ var binaryExpressionExecutors = map[lexer.TokenKind]binaryExpressionExecutorFn{}
5256

5357
func binaryExprExecutor(opts *Options, e ast.BinaryExpr) (expressionExecutor, error) {
5458
return func(data *model.Value) (*model.Value, error) {
59+
if e.Left == nil || e.Right == nil {
60+
return nil, fmt.Errorf("left and right expressions must be provided")
61+
}
5562

5663
exec, ok := binaryExpressionExecutors[e.Operator.Kind]
5764
if !ok {

execution/execute_branch.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ func branchExprExecutor(opts *Options, e ast.BranchExpr) (expressionExecutor, er
1313
res.MarkAsBranch()
1414

1515
if len(e.Exprs) == 0 {
16+
// No expressions given. We'll branch on the input data.
1617
if err := data.RangeSlice(func(_ int, value *model.Value) error {
1718
if err := res.Append(value); err != nil {
1819
return fmt.Errorf("failed to append branch result: %w", err)

execution/execute_branch_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,24 @@ func TestBranch(t *testing.T) {
125125
execution.WithUnstable(),
126126
},
127127
}.run)
128+
t.Run("map on branch", testCase{
129+
s: `branch([1], [2], [3]).map($this * 2).branch()`,
130+
outFn: func() *model.Value {
131+
r := model.NewSliceValue()
132+
r.MarkAsBranch()
133+
if err := r.Append(model.NewIntValue(2)); err != nil {
134+
t.Fatalf("unexpected error: %v", err)
135+
}
136+
if err := r.Append(model.NewIntValue(4)); err != nil {
137+
t.Fatalf("unexpected error: %v", err)
138+
}
139+
if err := r.Append(model.NewIntValue(6)); err != nil {
140+
t.Fatalf("unexpected error: %v", err)
141+
}
142+
return r
143+
},
144+
opts: []execution.ExecuteOptionFn{
145+
execution.WithUnstable(),
146+
},
147+
}.run)
128148
}

execution/execute_map.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ func mapExprExecutor(opts *Options, e ast.MapExpr) (expressionExecutor, error) {
2626
}); err != nil {
2727
return nil, fmt.Errorf("error ranging over slice: %w", err)
2828
}
29-
3029
return res, nil
3130
}, nil
3231
}

execution/execute_map_test.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package execution_test
33
import (
44
"testing"
55

6-
"github.com/tomwright/dasel/v3/internal/ptr"
76
"github.com/tomwright/dasel/v3/model"
87
"github.com/tomwright/dasel/v3/model/orderedmap"
98
)
@@ -38,7 +37,17 @@ func TestMap(t *testing.T) {
3837
)
3938
.map ( total )`,
4039
outFn: func() *model.Value {
41-
return model.NewValue([]any{ptr.To(int64(6)), ptr.To(int64(8)), ptr.To(int64(10))})
40+
res := model.NewSliceValue()
41+
if err := res.Append(model.NewValue(6)); err != nil {
42+
t.Fatal(err)
43+
}
44+
if err := res.Append(model.NewValue(8)); err != nil {
45+
t.Fatal(err)
46+
}
47+
if err := res.Append(model.NewValue(10)); err != nil {
48+
t.Fatal(err)
49+
}
50+
return res
4251
},
4352
}.run)
4453
}

execution/execute_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func (tc testCase) run(t *testing.T) {
4545
t.Fatal(err)
4646
}
4747
if !equal {
48-
t.Errorf("unexpected output: %v", cmp.Diff(exp.Interface(), res.Interface()))
48+
t.Errorf("unexpected output: %v\nexp: %s\ngot: %s", cmp.Diff(exp.Interface(), res.Interface()), exp.String(), res.String())
4949
}
5050

5151
expMeta := exp.Metadata

go.mod

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,26 @@ require (
88
github.com/pelletier/go-toml/v2 v2.2.2
99
gopkg.in/yaml.v3 v3.0.1
1010
)
11+
12+
require (
13+
github.com/atotto/clipboard v0.1.4 // indirect
14+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
15+
github.com/charmbracelet/bubbles v0.20.0 // indirect
16+
github.com/charmbracelet/bubbletea v1.1.2 // indirect
17+
github.com/charmbracelet/lipgloss v0.13.1 // indirect
18+
github.com/charmbracelet/x/ansi v0.4.0 // indirect
19+
github.com/charmbracelet/x/term v0.2.0 // indirect
20+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
21+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
22+
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
23+
github.com/mattn/go-isatty v0.0.20 // indirect
24+
github.com/mattn/go-localereader v0.0.1 // indirect
25+
github.com/mattn/go-runewidth v0.0.16 // indirect
26+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
27+
github.com/muesli/cancelreader v0.2.2 // indirect
28+
github.com/muesli/termenv v0.15.2 // indirect
29+
github.com/rivo/uniseg v0.4.7 // indirect
30+
golang.org/x/sync v0.8.0 // indirect
31+
golang.org/x/sys v0.26.0 // indirect
32+
golang.org/x/text v0.3.8 // indirect
33+
)

go.sum

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,56 @@ github.com/alecthomas/kong v1.2.1 h1:E8jH4Tsgv6wCRX2nGrdPyHDUCSG83WH2qE4XLACD33Q
44
github.com/alecthomas/kong v1.2.1/go.mod h1:rKTSFhbdp3Ryefn8x5MOEprnRFQ7nlmMC01GKhehhBM=
55
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
66
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
7+
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
8+
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
9+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
10+
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
11+
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
12+
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
13+
github.com/charmbracelet/bubbletea v1.1.2 h1:naQXF2laRxyLyil/i7fxdpiz1/k06IKquhm4vBfHsIc=
14+
github.com/charmbracelet/bubbletea v1.1.2/go.mod h1:9HIU/hBV24qKjlehyj8z1r/tR9TYTQEag+cWZnuXo8E=
15+
github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw=
16+
github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY=
17+
github.com/charmbracelet/lipgloss v0.13.1 h1:Oik/oqDTMVA01GetT4JdEC033dNzWoQHdWnHnQmXE2A=
18+
github.com/charmbracelet/lipgloss v0.13.1/go.mod h1:zaYVJ2xKSKEnTEEbX6uAHabh2d975RJ+0yfkFpRBz5U=
19+
github.com/charmbracelet/x/ansi v0.4.0 h1:NqwHA4B23VwsDn4H3VcNX1W1tOmgnvY1NDx5tOXdnOU=
20+
github.com/charmbracelet/x/ansi v0.4.0/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
21+
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
22+
github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
723
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
824
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
925
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
26+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
27+
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
1028
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
1129
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
30+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
31+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
1232
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
1333
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
34+
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
35+
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
36+
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
37+
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
38+
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
39+
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
40+
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
41+
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
42+
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
43+
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
44+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
45+
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
46+
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
47+
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
48+
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
49+
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
1450
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
1551
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
1652
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1753
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
54+
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
55+
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
56+
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
1857
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
1958
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
2059
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -24,6 +63,14 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
2463
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
2564
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
2665
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
66+
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
67+
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
68+
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
69+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
70+
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
71+
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
72+
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
73+
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
2774
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
2875
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
2976
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

internal/cli/command.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ type Globals struct {
1717
type CLI struct {
1818
Globals
1919

20-
Query QueryCmd `cmd:"" default:"withargs" help:"[default] Execute a query"`
21-
Version VersionCmd `cmd:"" help:"Print the version"`
20+
Query QueryCmd `cmd:"" default:"withargs" help:"[default] Execute a query"`
21+
Version VersionCmd `cmd:"" help:"Print the version"`
22+
Interactive InteractiveCmd `cmd:"" help:"Start an interactive session"`
2223
}
2324

2425
func MustRun(stdin io.Reader, stdout, stderr io.Writer) {
@@ -46,6 +47,7 @@ func Run(stdin io.Reader, stdout, stderr io.Writer) (*kong.Context, error) {
4647
},
4748
kong.Bind(&cli.Globals),
4849
kong.TypeMapper(reflect.TypeFor[*[]variable](), &variableMapper{}),
50+
kong.TypeMapper(reflect.TypeFor[*[]extReadWriteFlag](), &extReadWriteFlagMapper{}),
4951
kong.OptionFunc(func(k *kong.Kong) error {
5052
k.Stdout = cli.Stdout
5153
k.Stderr = cli.Stderr

0 commit comments

Comments
 (0)