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  }