...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package main
16
17 import (
18 "fmt"
19 "os"
20 "strconv"
21 "strings"
22 )
23
24 type PackageRegistry struct {
25 packagesByID map[string]*FlatPackage
26 stdlib map[string]string
27 bazelVersion []int
28 }
29
30 func NewPackageRegistry(bazelVersion string, pkgs ...*FlatPackage) *PackageRegistry {
31 pr := &PackageRegistry{
32 packagesByID: map[string]*FlatPackage{},
33 stdlib: map[string]string{},
34 bazelVersion: parseVersion(bazelVersion),
35 }
36 pr.Add(pkgs...)
37 return pr
38 }
39
40 func (pr *PackageRegistry) Add(pkgs ...*FlatPackage) *PackageRegistry {
41 for _, pkg := range pkgs {
42 pr.packagesByID[pkg.ID] = pkg
43
44 if pkg.IsStdlib() {
45 pr.stdlib[pkg.PkgPath] = pkg.ID
46 }
47 }
48 return pr
49 }
50
51 func (pr *PackageRegistry) ResolvePaths(prf PathResolverFunc) error {
52 for _, pkg := range pr.packagesByID {
53 pkg.ResolvePaths(prf)
54 pkg.FilterFilesForBuildTags()
55 }
56 return nil
57 }
58
59
60
61
62 func (pr *PackageRegistry) ResolveImports() error {
63 resolve := func(importPath string) string {
64 if pkgID, ok := pr.stdlib[importPath]; ok {
65 return pkgID
66 }
67
68 return ""
69 }
70
71 for _, pkg := range pr.packagesByID {
72 if err := pkg.ResolveImports(resolve); err != nil {
73 return err
74 }
75 testFp := pkg.MoveTestFiles()
76 if testFp != nil {
77 pr.packagesByID[testFp.ID] = testFp
78 }
79 }
80
81 return nil
82 }
83
84 func (pr *PackageRegistry) walk(acc map[string]*FlatPackage, root string) {
85 pkg := pr.packagesByID[root]
86
87 if pkg == nil {
88 fmt.Fprintf(os.Stderr, "Error: package ID not found %v\n", root)
89 return
90 }
91
92 acc[pkg.ID] = pkg
93 for _, pkgID := range pkg.Imports {
94 if _, ok := acc[pkgID]; !ok {
95 pr.walk(acc, pkgID)
96 }
97 }
98 }
99
100 func (pr *PackageRegistry) Match(labels []string) ([]string, []*FlatPackage) {
101 roots := map[string]struct{}{}
102
103 for _, label := range labels {
104
105 if pr.bazelVersion[0] >= 6 &&
106 !strings.HasPrefix(label, "@") {
107
108 label = fmt.Sprintf("@%s", label)
109 }
110
111 if label == RulesGoStdlibLabel {
112
113
114 for _, pkg := range pr.packagesByID {
115 if pkg.Standard {
116 roots[pkg.ID] = struct{}{}
117 }
118 }
119 } else {
120 roots[label] = struct{}{}
121
122 if _, ok := pr.packagesByID[label+"_xtest"]; ok {
123 roots[label+"_xtest"] = struct{}{}
124 }
125 }
126 }
127
128 walkedPackages := map[string]*FlatPackage{}
129 retRoots := make([]string, 0, len(roots))
130 for rootPkg := range roots {
131 retRoots = append(retRoots, rootPkg)
132 pr.walk(walkedPackages, rootPkg)
133 }
134
135 retPkgs := make([]*FlatPackage, 0, len(walkedPackages))
136 for _, pkg := range walkedPackages {
137 retPkgs = append(retPkgs, pkg)
138 }
139
140 return retRoots, retPkgs
141 }
142
143 func parseVersion(v string) []int {
144 parts := strings.Split(v, ".")
145 version := make([]int, len(parts))
146
147 var err error
148 for i, p := range parts {
149 version[i], err = strconv.Atoi(p)
150 if err != nil {
151
152 return []int{6, 0, 0}
153 }
154 }
155
156 return version
157 }
158
View as plain text