/
main.go
104 lines (97 loc) · 3 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
package udwGoImport
import (
"github.com/tachyon-protocol/udw/udwFile"
"github.com/tachyon-protocol/udw/udwGoSource/udwGoBuildCtx"
"go/build"
"path/filepath"
"strings"
)
type MustMulitGetPackageImportRequest struct {
AbsImportPathList []string
IgnoreImportPackageFromGoRoot bool
SimpleGoPathDirSearchNoError bool
BuildCtx *udwGoBuildCtx.Ctx
NotIgnoreImportC bool
}
func MustMulitGetPackageImport(req MustMulitGetPackageImportRequest) (resp MustMulitGetPackageImportResponse) {
if req.BuildCtx == nil {
req.BuildCtx = udwGoBuildCtx.NewCtxDefault()
}
GoBuildCtx := req.BuildCtx.ToGoBuildCtx()
firstGoPath := req.BuildCtx.GetFirstGoPathString()
importPathMapMap := map[string]map[string]struct{}{}
absImportPathToDirMap := map[string]string{}
seeImportPath := map[string]struct{}{}
thisParentList := []string{}
var readOnePackageFn func(AbsImportPath string)
readOnePackageFn = func(AbsImportPath string) {
thisParentList = append(thisParentList, AbsImportPath)
defer func() {
thisParentList = thisParentList[:len(thisParentList)-1]
}()
_, ok := seeImportPath[AbsImportPath]
if ok {
return
}
seeImportPath[AbsImportPath] = struct{}{}
pkg, err := GoBuildCtx.Import(AbsImportPath, "", 0)
if err != nil {
if strings.Contains(err.Error(), "no buildable Go source files") {
return
}
panic(err)
}
absImportPathToDirMap[AbsImportPath] = pkg.Dir
importPathMapMap[AbsImportPath] = map[string]struct{}{}
for _, s := range pkg.Imports {
if s == "C" {
if req.NotIgnoreImportC {
importPathMapMap[AbsImportPath][s] = struct{}{}
}
continue
}
if req.SimpleGoPathDirSearchNoError {
_, hasSeen := seeImportPath[s]
if hasSeen == false && udwFile.MustIsDir(filepath.Join(firstGoPath, "src", s)) == false {
continue
}
thisAbsImportPath := s
importPathMapMap[AbsImportPath][thisAbsImportPath] = struct{}{}
readOnePackageFn(thisAbsImportPath)
continue
}
thisPkg, err := GoBuildCtx.Import(s, pkg.Dir, build.FindOnly)
if err != nil {
if strings.Contains(err.Error(), "no buildable Go source files") {
continue
}
panic("ctxt.Import fail \n" + strings.Join(thisParentList, "\n") + "\n" + err.Error())
}
if req.IgnoreImportPackageFromGoRoot && strings.HasPrefix(thisPkg.Dir, req.BuildCtx.GetGoRoot()) == true {
continue
}
thisAbsImportPath := thisPkg.ImportPath
importPathMapMap[AbsImportPath][thisAbsImportPath] = struct{}{}
readOnePackageFn(thisAbsImportPath)
}
for p1 := range importPathMapMap[AbsImportPath] {
if p1 == "C" {
continue
}
if absImportPathToDirMap[p1] == "" {
panic("import " + p1 + " but not file from " + AbsImportPath)
}
}
}
readOnePackageTopFn := func(AbsImportPath string) {
thisParentList = thisParentList[:0]
readOnePackageFn(AbsImportPath)
}
for _, pkgPath := range req.AbsImportPathList {
readOnePackageTopFn(pkgPath)
}
return MustMulitGetPackageImportResponse{
absImportPathMapMap: importPathMapMap,
absImportPathToDirMap: absImportPathToDirMap,
}
}