-
Notifications
You must be signed in to change notification settings - Fork 37
/
list.go
111 lines (103 loc) · 2.61 KB
/
list.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
package main
import (
"bufio"
"bytes"
"context"
"fmt"
"io"
"github.com/ktock/buildg/pkg/buildkit"
"github.com/moby/buildkit/solver/pb"
"github.com/urfave/cli"
)
const defaultListRange = 3
func listCommand(_ context.Context, hCtx *handlerContext) cli.Command {
return cli.Command{
Name: "list",
Aliases: []string{"ls", "l"},
Usage: "list source lines",
UsageText: "list [OPTIONS]",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "all",
Usage: "show all lines",
},
cli.IntFlag{
Name: "A",
Usage: "Print the specified number of lines after the current line",
Value: defaultListRange,
},
cli.IntFlag{
Name: "B",
Usage: "Print the specified number of lines before the current line",
Value: defaultListRange,
},
cli.IntFlag{
Name: "range",
Usage: "Print the specified number of lines before and after the current line",
Value: defaultListRange,
},
},
Action: func(clicontext *cli.Context) error {
lineRange := clicontext.Int("range")
before, after := lineRange, lineRange
if b := clicontext.Int("B"); b != defaultListRange {
before = b
}
if a := clicontext.Int("A"); a != defaultListRange {
after = a
}
printLines(hCtx.handler, hCtx.stdout, hCtx.locs, before, after, clicontext.Bool("all"))
return nil
},
}
}
func printLines(h *buildkit.Handler, w io.Writer, locs []*buildkit.Location, before, after int, all bool) {
sources := make(map[*pb.SourceInfo][]*pb.Range)
for _, l := range locs {
sources[l.Source] = append(sources[l.Source], l.Ranges...)
}
for source, ranges := range sources {
if len(ranges) == 0 {
continue
}
fmt.Fprintf(w, "Filename: %q\n", source.Filename)
scanner := bufio.NewScanner(bytes.NewReader(source.Data))
lastLinePrinted := false
firstPrint := true
for i := 1; scanner.Scan(); i++ {
doPrint := false
target := false
for _, r := range ranges {
if all || int(r.Start.Line)-before <= i && i <= int(r.End.Line)+after {
doPrint = true
if int(r.Start.Line) <= i && i <= int(r.End.Line) {
target = true
break
}
}
}
if !doPrint {
lastLinePrinted = false
continue
}
if !lastLinePrinted && !firstPrint {
fmt.Fprintln(w, "----------------")
}
prefix := " "
h.Breakpoints().ForEach(func(key string, b buildkit.Breakpoint) bool {
if b.IsMarked(source, int64(i)) {
prefix = "*"
return false
}
return true
})
prefix2 := " "
if target {
prefix2 = "=>"
}
fmt.Fprintln(w, prefix+prefix2+fmt.Sprintf("%4d| ", i)+scanner.Text())
lastLinePrinted = true
firstPrint = false
}
}
}