-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
109 lines (86 loc) · 1.82 KB
/
main.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
package main
import (
"bufio"
"flag"
"fmt"
"os"
"sort"
"strings"
)
type Pkg struct {
Deps map[string]bool
ReverseDeps map[string]bool
}
type TrailEntry struct {
PkgNames []string
PkgNext int
}
func main() {
flag.Parse()
pkgs := readStdinPkgs()
printed := make(map[string]bool)
for _, pkgName := range flag.Args() {
printRecursiveReverseDeps(pkgs, printed, pkgName)
}
}
func readStdinPkgs() map[string]Pkg {
pkgs := make(map[string]Pkg)
s := bufio.NewScanner(os.Stdin)
for s.Scan() {
entries := strings.Split(s.Text(), " ")
node := entries[0]
dep := entries[1]
nodePkg := getPkg(pkgs, node)
depPkg := getPkg(pkgs, dep)
nodePkg.Deps[dep] = true
depPkg.ReverseDeps[node] = true
}
return pkgs
}
func printRecursiveReverseDeps(pkgs map[string]Pkg, printed map[string]bool, pkgName string) {
trail := []*TrailEntry{{
PkgNames: []string{pkgName},
PkgNext: 0,
}}
for len(trail) > 0 {
current := trail[len(trail)-1]
if current.PkgNext >= len(current.PkgNames) {
trail = trail[:len(trail)-1]
continue
}
nextName := current.PkgNames[current.PkgNext]
current.PkgNext++
suffix := ""
if printed[nextName] {
suffix = " ^^"
}
fmt.Printf("%s%s%s\n", strings.Repeat("| ", len(trail)-1), nextName, suffix)
if printed[nextName] {
continue
}
nextPkg := pkgs[nextName]
nextPkgNames := make([]string, len(nextPkg.ReverseDeps))
i := 0
for k := range nextPkg.ReverseDeps {
nextPkgNames[i] = k
i++
}
sort.Strings(nextPkgNames)
trail = append(trail, &TrailEntry{
PkgNames: nextPkgNames,
PkgNext: 0,
})
printed[nextName] = true
}
}
func getPkg(pkgs map[string]Pkg, name string) Pkg {
pkg, ok := pkgs[name]
if !ok {
pkg = Pkg{
Deps: make(map[string]bool),
ReverseDeps: make(map[string]bool),
}
pkgs[name] = pkg
}
return pkg
}