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  }