-
Notifications
You must be signed in to change notification settings - Fork 0
/
check.go
141 lines (120 loc) · 3.16 KB
/
check.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
139
140
141
package deputil
import (
"path/filepath"
"github.com/tsaikd/KDGoLib/errutil"
"github.com/tsaikd/KDGoLib/futil"
"github.com/tsaikd/tools/go/vcs"
)
// errors
var (
ErrorDepNoFound1 = errutil.NewFactory("dependency %q not found")
ErrorDepRevMismatch4 = errutil.NewFactory("dependency %q revision expected %q but got %q in %q")
)
// Check package dependency version by package Godeps.json
func Check(dir string, all bool) (err error) {
done := map[string]bool{}
mismatches := []error{}
if dir, err = filepath.Abs(dir); err != nil {
return
}
if err = checkDir(dir, all, done, &mismatches); err != nil {
return
}
for _, err = range mismatches {
errutil.Trace(err)
}
return errutil.NewErrors(mismatches...)
}
func checkDir(dir string, all bool, done map[string]bool, mismatches *[]error) (err error) {
if godepsJSON, err := parsePackageGoDeps(dir); err == nil {
if err = checkJSON(godepsJSON, dir, all, done, mismatches); err != nil {
return err
}
}
return
}
func checkJSON(godepsJSON JSON, dir string, all bool, done map[string]bool, mismatches *[]error) (err error) {
pkg, err := buildContext.ImportDir(dir, 0)
if err != nil {
return
}
for _, dep := range godepsJSON.Deps {
if done[dep.ImportPath] {
continue
}
done[dep.ImportPath] = true
var deproot string
srcroots := genVendorsRoot(dir, pkg.SrcRoot)
if deproot, err = checkPackageRoots(srcroots, dep.ImportPath, dep.Rev, all); err != nil {
switch errutil.FactoryOf(err) {
case ErrorDepRevMismatch4:
*mismatches = append(*mismatches, err)
default:
return
}
}
if all {
var subjson JSON
deppath := filepath.Join(deproot, dep.ImportPath)
if subjson, err = parsePackageGoDeps(deppath); err == nil {
if err = checkJSON(subjson, deppath, all, done, mismatches); err != nil {
return
}
}
}
}
return nil
}
func checkPackageRoots(srcroots []string, importPath string, rev string, all bool) (pkgroot string, err error) {
found := false
for _, srcroot := range srcroots {
if err = checkPackage(srcroot, importPath, rev); err != nil {
switch errutil.FactoryOf(err) {
case ErrorDepNoFound1:
continue
case ErrorDepRevMismatch4:
if found {
errutil.TraceWrap(err, ErrorWarning.New(nil))
continue
}
return "", err
default:
return "", err
}
} else {
found = true
pkgroot = srcroot
}
}
if found {
return pkgroot, nil
}
return "", ErrorDepNoFound1.New(nil, importPath)
}
func checkPackage(srcroot string, importPath string, rev string) (err error) {
repo, err := vcs.RepoRootForImportPath(importPath, false)
if err != nil {
return ErrorGetRepoInfo1.New(err, importPath)
}
dir := filepath.Join(srcroot, repo.Root)
if !futil.IsExist(dir) {
return ErrorDepNoFound1.New(nil, repo.Root)
}
identify, err := repo.VCS.Identify(dir)
if err != nil {
return
}
if identify != rev {
return ErrorDepRevMismatch4.New(nil, repo.Root, rev, identify, srcroot)
}
return nil
}
func genVendorsRoot(dir string, srcroot string) []string {
roots := []string{}
for len(dir) > len(srcroot) {
roots = append(roots, filepath.Join(dir, "vendor"))
dir = filepath.Dir(dir)
}
roots = append(roots, srcroot)
return roots
}