-
Notifications
You must be signed in to change notification settings - Fork 0
/
registry.go
88 lines (71 loc) · 2.11 KB
/
registry.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
package golog
import (
"runtime"
"sort"
"strings"
"sync"
)
type Registry struct {
mutex sync.RWMutex
pkgPathNames map[string]string
pkgNameConfigs map[string]*DerivedConfig
pkgPathConfigs map[string]*DerivedConfig
}
func (r *Registry) AddPackageConfig(pkgName string, config *DerivedConfig) (pkgPath string) {
r.mutex.Lock()
defer r.mutex.Unlock()
if r.pkgPathNames == nil {
r.pkgPathNames = make(map[string]string)
r.pkgNameConfigs = make(map[string]*DerivedConfig)
r.pkgPathConfigs = make(map[string]*DerivedConfig)
}
pkgPath = getCallingPackageImportPath(2)
if _, exists := r.pkgNameConfigs[pkgName]; exists {
// Panicing because AddPackageConfig is one time global
// setup before any other error handlers
panic("package name config already added: " + pkgName)
}
if _, exists := r.pkgPathConfigs[pkgPath]; exists {
// Panicing because AddPackageConfig is one time global
// setup before any other error handlers
panic("package path config already added: " + pkgPath)
}
r.pkgPathNames[pkgPath] = pkgName
r.pkgNameConfigs[pkgName] = config
r.pkgPathConfigs[pkgPath] = config
return pkgPath
}
func (r *Registry) ConfigOrNilByPackageName(pkgName string) *DerivedConfig {
r.mutex.RLock()
defer r.mutex.RUnlock()
return r.pkgNameConfigs[pkgName]
}
func (r *Registry) ConfigOrNilByPackagePath(pkgPath string) *DerivedConfig {
r.mutex.RLock()
defer r.mutex.RUnlock()
return r.pkgPathConfigs[pkgPath]
}
func (r *Registry) PackagesSortedByName() (paths, names []string) {
r.mutex.RLock()
defer r.mutex.RUnlock()
names = make([]string, 0, len(r.pkgPathNames))
for _, name := range r.pkgPathNames {
names = append(names, name)
}
sort.Strings(names)
paths = make([]string, len(r.pkgPathNames))
for i, name := range names {
paths[i] = r.pkgPathNames[name]
}
return paths, names
}
func getCallingPackageImportPath(skip int) string {
stack := make([]uintptr, 1)
num := runtime.Callers(skip+2, stack)
if num != len(stack) {
panic("insufficient call stack")
}
frame, _ := runtime.CallersFrames(stack).Next()
name := frame.Func.Name()
return name[:strings.LastIndexByte(name, '.')]
}