...
1 package cmd
2
3 import (
4 "fmt"
5 "reflect"
6 "sort"
7 "sync"
8
9 "github.com/letsencrypt/validator/v10"
10 )
11
12 type ConfigValidator struct {
13 Config interface{}
14 Validators map[string]validator.Func
15 }
16
17 var registry struct {
18 sync.Mutex
19 commands map[string]func()
20 configs map[string]*ConfigValidator
21 }
22
23
24
25
26
27 func RegisterCommand(name string, f func(), cv *ConfigValidator) {
28 registry.Lock()
29 defer registry.Unlock()
30
31 if registry.commands == nil {
32 registry.commands = make(map[string]func())
33 }
34
35 if registry.commands[name] != nil {
36 panic(fmt.Sprintf("command %q was registered twice", name))
37 }
38 registry.commands[name] = f
39
40 if cv == nil {
41 return
42 }
43
44 if registry.configs == nil {
45 registry.configs = make(map[string]*ConfigValidator)
46 }
47
48 if registry.configs[name] != nil {
49 panic(fmt.Sprintf("config validator for command %q was registered twice", name))
50 }
51 registry.configs[name] = cv
52 }
53
54 func LookupCommand(name string) func() {
55 registry.Lock()
56 defer registry.Unlock()
57 return registry.commands[name]
58 }
59
60 func AvailableCommands() []string {
61 registry.Lock()
62 defer registry.Unlock()
63 var avail []string
64 for name := range registry.commands {
65 avail = append(avail, name)
66 }
67 sort.Strings(avail)
68 return avail
69 }
70
71
72
73
74 func LookupConfigValidator(name string) *ConfigValidator {
75 registry.Lock()
76 defer registry.Unlock()
77 if registry.configs[name] == nil {
78 return nil
79 }
80
81
82
83 copy := reflect.New(reflect.ValueOf(
84 registry.configs[name].Config).Elem().Type(),
85 ).Interface()
86
87 return &ConfigValidator{
88 Config: copy,
89 Validators: registry.configs[name].Validators,
90 }
91 }
92
93
94
95 func AvailableConfigValidators() []string {
96 registry.Lock()
97 defer registry.Unlock()
98 var avail []string
99 for name := range registry.configs {
100 avail = append(avail, name)
101 }
102 sort.Strings(avail)
103 return avail
104 }
105
View as plain text