github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/actor/pluginaction/uninstall.go (about)

     1  package pluginaction
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/exec"
     7  	"time"
     8  )
     9  
    10  // PluginNotFoundError is an error returned when a plugin is not found.
    11  type PluginNotFoundError struct {
    12  	PluginName string
    13  }
    14  
    15  // Error outputs a plugin not found error message.
    16  func (e PluginNotFoundError) Error() string {
    17  	return fmt.Sprintf("Plugin name %s does not exist.", e.PluginName)
    18  }
    19  
    20  //go:generate counterfeiter . PluginUninstaller
    21  
    22  type PluginUninstaller interface {
    23  	Run(pluginPath string, command string) error
    24  }
    25  
    26  // PluginBinaryRemoveFailedError is returned when running the plugin binary fails.
    27  type PluginBinaryRemoveFailedError struct {
    28  	Err error
    29  }
    30  
    31  func (p PluginBinaryRemoveFailedError) Error() string {
    32  	return p.Err.Error()
    33  }
    34  
    35  // PluginExecuteError is returned when running the plugin binary fails.
    36  type PluginExecuteError struct {
    37  	Err error
    38  }
    39  
    40  func (p PluginExecuteError) Error() string {
    41  	return p.Err.Error()
    42  }
    43  
    44  func (actor Actor) UninstallPlugin(uninstaller PluginUninstaller, name string) error {
    45  	plugin, exist := actor.config.GetPlugin(name)
    46  	if !exist {
    47  		return PluginNotFoundError{PluginName: name}
    48  	}
    49  
    50  	var binaryErr error
    51  
    52  	if actor.FileExists(plugin.Location) {
    53  		err := uninstaller.Run(plugin.Location, "CLI-MESSAGE-UNINSTALL")
    54  		if err != nil {
    55  			switch err.(type) {
    56  			case *exec.ExitError:
    57  				binaryErr = PluginExecuteError{
    58  					Err: err,
    59  				}
    60  			case *os.PathError:
    61  				binaryErr = PluginExecuteError{
    62  					Err: err,
    63  				}
    64  			default:
    65  				return err
    66  			}
    67  		}
    68  
    69  		// No test for sleeping for 500 ms for parity with pre-refactored behavior.
    70  		time.Sleep(500 * time.Millisecond)
    71  
    72  		err = os.Remove(plugin.Location)
    73  		if err != nil && !os.IsNotExist(err) {
    74  			if _, isPathError := err.(*os.PathError); isPathError {
    75  				binaryErr = PluginBinaryRemoveFailedError{
    76  					Err: err,
    77  				}
    78  			} else {
    79  				return err
    80  			}
    81  		}
    82  	}
    83  
    84  	actor.config.RemovePlugin(name)
    85  	err := actor.config.WritePluginConfig()
    86  	if err != nil {
    87  		return err
    88  	}
    89  
    90  	return binaryErr
    91  }