github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/cf/configuration/pluginconfig/plugin_config.go (about) 1 package pluginconfig 2 3 import ( 4 "sync" 5 6 "code.cloudfoundry.org/cli/cf/configuration" 7 ) 8 9 //go:generate counterfeiter . PluginConfiguration 10 11 type PluginConfiguration interface { 12 Plugins() map[string]PluginMetadata 13 SetPlugin(string, PluginMetadata) 14 GetPluginPath() string 15 RemovePlugin(string) 16 ListCommands() []string 17 } 18 19 type PluginConfig struct { 20 mutex *sync.RWMutex 21 initOnce *sync.Once 22 persistor configuration.Persistor 23 onError func(error) 24 data *PluginData 25 pluginPath string 26 } 27 28 func NewPluginConfig(errorHandler func(error), persistor configuration.Persistor, pluginPath string) *PluginConfig { 29 return &PluginConfig{ 30 data: NewData(), 31 mutex: new(sync.RWMutex), 32 initOnce: new(sync.Once), 33 persistor: persistor, 34 onError: errorHandler, 35 pluginPath: pluginPath, 36 } 37 } 38 39 func (c *PluginConfig) GetPluginPath() string { 40 return c.pluginPath 41 } 42 43 func (c *PluginConfig) Plugins() map[string]PluginMetadata { 44 c.read() 45 return c.data.Plugins 46 } 47 48 func (c *PluginConfig) SetPlugin(name string, metadata PluginMetadata) { 49 if c.data.Plugins == nil { 50 c.data.Plugins = make(map[string]PluginMetadata) 51 } 52 c.write(func() { 53 c.data.Plugins[name] = metadata 54 }) 55 } 56 57 func (c *PluginConfig) RemovePlugin(name string) { 58 c.write(func() { 59 delete(c.data.Plugins, name) 60 }) 61 } 62 63 func (c *PluginConfig) ListCommands() []string { 64 plugins := c.Plugins() 65 allCommands := []string{} 66 67 for _, plugin := range plugins { 68 for _, command := range plugin.Commands { 69 allCommands = append(allCommands, command.Name) 70 } 71 } 72 73 return allCommands 74 } 75 76 func (c *PluginConfig) init() { 77 //only read from disk if it was never read 78 c.initOnce.Do(func() { 79 err := c.persistor.Load(c.data) 80 if err != nil { 81 c.onError(err) 82 } 83 }) 84 } 85 86 func (c *PluginConfig) read() { 87 c.mutex.RLock() 88 defer c.mutex.RUnlock() 89 c.init() 90 } 91 92 func (c *PluginConfig) write(cb func()) { 93 c.mutex.Lock() 94 defer c.mutex.Unlock() 95 c.init() 96 97 cb() 98 99 err := c.persistor.Save(c.data) 100 if err != nil { 101 c.onError(err) 102 } 103 } 104 105 func (c *PluginConfig) Close() { 106 c.read() 107 // perform a read to ensure write lock has been cleared 108 }