github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/cf/configuration/plugin_config/plugin_config.go (about) 1 package plugin_config 2 3 import ( 4 "path/filepath" 5 "sync" 6 7 "github.com/cloudfoundry/cli/cf/configuration" 8 "github.com/cloudfoundry/cli/cf/configuration/config_helpers" 9 ) 10 11 type PluginConfiguration interface { 12 Plugins() map[string]PluginMetadata 13 SetPlugin(string, PluginMetadata) 14 GetPluginPath() string 15 RemovePlugin(string) 16 } 17 18 type PluginConfig struct { 19 mutex *sync.RWMutex 20 initOnce *sync.Once 21 persistor configuration.Persistor 22 onError func(error) 23 data *PluginData 24 pluginPath string 25 } 26 27 func NewPluginConfig(errorHandler func(error)) *PluginConfig { 28 pluginPath := filepath.Join(config_helpers.PluginRepoDir(), ".cf", "plugins") 29 return &PluginConfig{ 30 data: NewData(), 31 mutex: new(sync.RWMutex), 32 initOnce: new(sync.Once), 33 persistor: configuration.NewDiskPersistor(filepath.Join(pluginPath, "config.json")), 34 onError: errorHandler, 35 pluginPath: pluginPath, 36 } 37 } 38 39 /* getter methods */ 40 func (c *PluginConfig) GetPluginPath() string { 41 return c.pluginPath 42 } 43 44 func (c *PluginConfig) Plugins() map[string]PluginMetadata { 45 c.read() 46 return c.data.Plugins 47 } 48 49 /* setter methods */ 50 func (c *PluginConfig) SetPlugin(name string, metadata PluginMetadata) { 51 if c.data.Plugins == nil { 52 c.data.Plugins = make(map[string]PluginMetadata) 53 } 54 c.write(func() { 55 c.data.Plugins[name] = metadata 56 }) 57 } 58 59 func (c *PluginConfig) RemovePlugin(name string) { 60 c.write(func() { 61 delete(c.data.Plugins, name) 62 }) 63 } 64 65 /* Functions that handel locking */ 66 func (c *PluginConfig) init() { 67 //only read from disk if it was never read 68 c.initOnce.Do(func() { 69 err := c.persistor.Load(c.data) 70 if err != nil { 71 c.onError(err) 72 } 73 }) 74 } 75 76 func (c *PluginConfig) read() { 77 c.mutex.RLock() 78 defer c.mutex.RUnlock() 79 c.init() 80 } 81 82 func (c *PluginConfig) write(cb func()) { 83 c.mutex.Lock() 84 defer c.mutex.Unlock() 85 c.init() 86 87 cb() 88 89 err := c.persistor.Save(c.data) 90 if err != nil { 91 c.onError(err) 92 } 93 } 94 95 // CLOSERS 96 func (c *PluginConfig) Close() { 97 c.read() 98 // perform a read to ensure write lock has been cleared 99 }