-
Notifications
You must be signed in to change notification settings - Fork 37
/
break.go
138 lines (126 loc) · 3.6 KB
/
break.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package main
import (
"context"
"fmt"
"strconv"
"text/tabwriter"
"github.com/ktock/buildg/pkg/buildkit"
"github.com/urfave/cli"
)
func breakCommand(_ context.Context, hCtx *handlerContext) cli.Command {
return cli.Command{
Name: "break",
Aliases: []string{"b"},
Usage: "set a breakpoint",
UsageText: `break BREAKPOINT
The following value can be set as a BREAKPOINT
NUMBER breaks on line number in Dockerfile
on-fail breaks on step that returns an error
`,
Action: func(clicontext *cli.Context) error {
bp := clicontext.Args().First()
if bp == "" {
return fmt.Errorf("breakpoint must be set")
}
h := hCtx.handler
var key string
var b buildkit.Breakpoint
if bp == "on-fail" {
key = "on-fail"
b = buildkit.NewOnFailBreakpoint()
} else if l, err := strconv.ParseInt(bp, 10, 64); err == nil {
b = buildkit.NewLineBreakpoint(hCtx.locs[0].Source.Filename, l)
}
if b == nil {
return fmt.Errorf("cannot parse breakpoint %q", bp)
}
_, err := h.Breakpoints().Add(key, b)
return err
},
}
}
func breakpointsCommand(_ context.Context, hCtx *handlerContext) cli.Command {
return cli.Command{
Name: "breakpoints",
Aliases: []string{"bp"},
Usage: "Show breakpoints key-value pairs",
UsageText: "breakpoints",
Action: func(clicontext *cli.Context) error {
tw := tabwriter.NewWriter(hCtx.stdout, 4, 8, 4, ' ', 0)
fmt.Fprintln(tw, "KEY\tDESCRIPTION")
hCtx.handler.Breakpoints().ForEach(func(key string, b buildkit.Breakpoint) bool {
fmt.Fprintf(tw, "%s\t%s\n", key, b)
return true
})
tw.Flush()
return nil
},
}
}
func clearCommand(_ context.Context, hCtx *handlerContext) cli.Command {
return cli.Command{
Name: "clear",
Usage: "Clear a breakpoint. Specify breakpoint key.",
UsageText: `clear BREAKPOINT_KEY
BREAKPOINT_KEY is the key of a breakpoint which is printed when executing "breakpoints" command.
`,
Action: func(clicontext *cli.Context) error {
bpKey := clicontext.Args().First()
if bpKey == "" {
return fmt.Errorf("breakpoint key must be set")
}
if _, ok := hCtx.handler.Breakpoints().Get(bpKey); !ok {
return fmt.Errorf("breakpoint %q not found", bpKey)
}
hCtx.handler.Breakpoints().Clear(bpKey)
return nil
},
}
}
func clearAllCommand(_ context.Context, hCtx *handlerContext) cli.Command {
return cli.Command{
Name: "clearall",
Usage: "Clear all breakpoints",
UsageText: "clearall",
Action: func(clicontext *cli.Context) error {
hCtx.handler.Breakpoints().ClearAll()
return nil
},
}
}
func nextCommand(_ context.Context, hCtx *handlerContext) cli.Command {
return cli.Command{
Name: "next",
Aliases: []string{"n"},
Usage: "Proceed to the next line",
UsageText: "next",
Action: func(clicontext *cli.Context) error {
hCtx.handler.BreakEachVertex(true)
hCtx.continueRead = false
return nil
},
}
}
func continueCommand(_ context.Context, hCtx *handlerContext) cli.Command {
return cli.Command{
Name: "continue",
Aliases: []string{"c"},
Usage: "Proceed to the next or the specified breakpoint",
UsageText: `continue [BREAKPOINT_KEY]
Optional arg BREAKPOINT_KEY is the key of a breakpoint until which continue the build.
Use "breakpoints" command to list all registered breakpoints.
`,
Action: func(clicontext *cli.Context) error {
bp := clicontext.Args().First()
if bp != "" {
if _, ok := hCtx.handler.Breakpoints().Get(bp); !ok {
return fmt.Errorf("unknown breakpoint %v", bp)
}
hCtx.targetBreakpoint = bp
}
hCtx.handler.BreakEachVertex(false)
hCtx.continueRead = false
return nil
},
}
}