...
1
16
17
18
19
20 package main
21
22 import (
23 "bytes"
24 "encoding/json"
25 "flag"
26 "fmt"
27 "io"
28 "log"
29 "os"
30 "regexp"
31 )
32
33 var (
34 exclude = flag.String("exclude", "", "skip packages regex pattern (e.g. '^k8s.io/kubernetes/')")
35 restrict = flag.String("restrict", "", "restricted dependencies regex pattern (e.g. '^k8s.io/(apimachinery|client-go)/')")
36 )
37
38 type goPackage struct {
39 Name string
40 ImportPath string
41 Imports []string
42 TestImports []string
43 XTestImports []string
44 }
45
46 func main() {
47 flag.Parse()
48
49 args := flag.Args()
50
51 if len(args) != 1 {
52 log.Fatalf("usage: dependencycheck <json-dep-file> (e.g. 'go list -mod=vendor -test -deps -json ./vendor/...')")
53 }
54 if *restrict == "" {
55 log.Fatalf("Must specify restricted regex pattern")
56 }
57 depsPattern, err := regexp.Compile(*restrict)
58 if err != nil {
59 log.Fatalf("Error compiling restricted dependencies regex: %v", err)
60 }
61 var excludePattern *regexp.Regexp
62 if *exclude != "" {
63 excludePattern, err = regexp.Compile(*exclude)
64 if err != nil {
65 log.Fatalf("Error compiling excluded package regex: %v", err)
66 }
67 }
68 b, err := os.ReadFile(args[0])
69 if err != nil {
70 log.Fatalf("Error reading dependencies file: %v", err)
71 }
72
73 packages := []goPackage{}
74 decoder := json.NewDecoder(bytes.NewBuffer(b))
75 for {
76 pkg := goPackage{}
77 if err := decoder.Decode(&pkg); err != nil {
78 if err == io.EOF {
79 break
80 }
81 log.Fatalf("Error unmarshaling dependencies file: %v", err)
82 }
83 packages = append(packages, pkg)
84 }
85
86 violations := map[string][]string{}
87 for _, p := range packages {
88 if excludePattern != nil && excludePattern.MatchString(p.ImportPath) {
89 continue
90 }
91 importViolations := []string{}
92 allImports := []string{}
93 allImports = append(allImports, p.Imports...)
94 allImports = append(allImports, p.TestImports...)
95 allImports = append(allImports, p.XTestImports...)
96 for _, i := range allImports {
97 if depsPattern.MatchString(i) {
98 importViolations = append(importViolations, i)
99 }
100 }
101 if len(importViolations) > 0 {
102 violations[p.ImportPath] = importViolations
103 }
104 }
105
106 if len(violations) > 0 {
107 for k, v := range violations {
108 fmt.Printf("Found dependency violations in package %s:\n", k)
109 for _, a := range v {
110 fmt.Println("--> " + a)
111 }
112 }
113 log.Fatal("Found restricted dependency violations in packages")
114 }
115 }
116
View as plain text