-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdebug.go
More file actions
123 lines (100 loc) · 2.35 KB
/
debug.go
File metadata and controls
123 lines (100 loc) · 2.35 KB
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
package needle
import (
"fmt"
"io"
"os"
"sort"
"strings"
)
type GraphInfo struct {
Services []ServiceInfo
}
type ServiceInfo struct {
Key string
Dependencies []string
Dependents []string
Instantiated bool
Scope string
}
func (c *Container) Graph() GraphInfo {
keys := c.internal.Keys()
sort.Strings(keys)
graph := c.internal.Graph()
services := make([]ServiceInfo, 0, len(keys))
for _, key := range keys {
deps := graph.GetDependencies(key)
dependents := graph.GetDependents(key)
_, instantiated := c.internal.GetInstance(key)
services = append(
services, ServiceInfo{
Key: key,
Dependencies: deps,
Dependents: dependents,
Instantiated: instantiated,
},
)
}
return GraphInfo{Services: services}
}
func (c *Container) PrintGraph() {
c.FprintGraph(os.Stdout)
}
func (c *Container) FprintGraph(w io.Writer) {
info := c.Graph()
if len(info.Services) == 0 {
_, _ = fmt.Fprintln(w, "(empty container)")
return
}
for _, svc := range info.Services {
status := "○"
if svc.Instantiated {
status = "●"
}
if len(svc.Dependencies) == 0 {
_, _ = fmt.Fprintf(w, "%s %s\n", status, svc.Key)
} else {
_, _ = fmt.Fprintf(w, "%s %s ← %s\n", status, svc.Key, strings.Join(svc.Dependencies, ", "))
}
}
}
func (c *Container) SprintGraph() string {
var sb strings.Builder
c.FprintGraph(&sb)
return sb.String()
}
func (c *Container) PrintGraphDOT() {
c.FprintGraphDOT(os.Stdout)
}
func (c *Container) FprintGraphDOT(w io.Writer) {
info := c.Graph()
_, _ = fmt.Fprintln(w, "digraph dependencies {")
_, _ = fmt.Fprintln(w, " rankdir=LR;")
_, _ = fmt.Fprintln(w, " node [shape=box];")
for _, svc := range info.Services {
label := escapeLabel(svc.Key)
style := ""
if svc.Instantiated {
style = ", style=filled, fillcolor=lightblue"
}
_, _ = fmt.Fprintf(w, " %q [label=%q%s];\n", svc.Key, label, style)
}
_, _ = fmt.Fprintln(w)
for _, svc := range info.Services {
for _, dep := range svc.Dependencies {
_, _ = fmt.Fprintf(w, " %q -> %q;\n", svc.Key, dep)
}
}
_, _ = fmt.Fprintln(w, "}")
}
func (c *Container) SprintGraphDOT() string {
var sb strings.Builder
c.FprintGraphDOT(&sb)
return sb.String()
}
func escapeLabel(s string) string {
s = strings.ReplaceAll(s, "*", "")
if idx := strings.LastIndex(s, "/"); idx != -1 {
s = s[idx+1:]
}
return s
}