github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/runners/clean/uninstall.go (about)

     1  package clean
     2  
     3  import (
     4  	"os"
     5  	"time"
     6  
     7  	"github.com/ActiveState/cli/internal/analytics"
     8  	"github.com/ActiveState/cli/internal/config"
     9  	"github.com/ActiveState/cli/internal/constants"
    10  	"github.com/ActiveState/cli/internal/errs"
    11  	"github.com/ActiveState/cli/internal/events"
    12  	"github.com/ActiveState/cli/internal/locale"
    13  	"github.com/ActiveState/cli/internal/logging"
    14  	"github.com/ActiveState/cli/internal/output"
    15  	"github.com/ActiveState/cli/internal/primer"
    16  	"github.com/ActiveState/cli/internal/svcctl"
    17  )
    18  
    19  type promptable interface {
    20  	Confirm(title, message string, defaultChoice *bool) (bool, error)
    21  	Select(title, message string, choices []string, defaultChoice *string) (string, error)
    22  }
    23  
    24  type Uninstall struct {
    25  	out    output.Outputer
    26  	prompt promptable
    27  	cfg    *config.Instance
    28  	ipComm svcctl.IPCommunicator
    29  	an     analytics.Dispatcher
    30  }
    31  
    32  type UninstallParams struct {
    33  	Force          bool
    34  	NonInteractive bool
    35  	All            bool
    36  	Prompt         bool
    37  }
    38  
    39  type primeable interface {
    40  	primer.Outputer
    41  	primer.Prompter
    42  	primer.Configurer
    43  	primer.IPCommunicator
    44  	primer.Analyticer
    45  }
    46  
    47  func NewUninstall(prime primeable) (*Uninstall, error) {
    48  	return newUninstall(prime.Output(), prime.Prompt(), prime.Config(), prime.IPComm(), prime.Analytics())
    49  }
    50  
    51  func newUninstall(out output.Outputer, prompt promptable, cfg *config.Instance, ipComm svcctl.IPCommunicator, an analytics.Dispatcher) (*Uninstall, error) {
    52  	return &Uninstall{
    53  		out:    out,
    54  		prompt: prompt,
    55  		cfg:    cfg,
    56  		ipComm: ipComm,
    57  		an:     an,
    58  	}, nil
    59  }
    60  
    61  func (u *Uninstall) Run(params *UninstallParams) error {
    62  	if os.Getenv(constants.ActivatedStateEnvVarName) != "" {
    63  		return locale.NewInputError("err_uninstall_activated")
    64  	}
    65  
    66  	err := verifyInstallation()
    67  	if err != nil {
    68  		return errs.Wrap(err, "Could not verify installation")
    69  	}
    70  
    71  	if params.Prompt {
    72  		choices := []string{
    73  			locale.Tl("uninstall_prompt", "Uninstall the State Tool, but keep runtime cache and configuration files"),
    74  			locale.Tl("uninstall_prompt_all", "Completely uninstall the State Tool, including runtime cache and configuration files"),
    75  		}
    76  		selection, err := u.prompt.Select("", "", choices, new(string))
    77  		if err != nil {
    78  			return locale.WrapError(err, "err_uninstall_prompt", "Could not read uninstall option")
    79  		}
    80  		if selection == choices[1] {
    81  			params.All = true
    82  		}
    83  	} else if !params.Force {
    84  		defaultChoice := params.NonInteractive
    85  		confirmMessage := locale.T("uninstall_confirm")
    86  		if params.All {
    87  			confirmMessage = locale.T("uninstall_confirm_all")
    88  		}
    89  		ok, err := u.prompt.Confirm(locale.T("confirm"), confirmMessage, &defaultChoice)
    90  		if err != nil {
    91  			return locale.WrapError(err, "err_uninstall_confirm", "Could not confirm uninstall choice")
    92  		}
    93  		if !ok {
    94  			return locale.NewInputError("err_uninstall_aborted", "Uninstall aborted by user")
    95  		}
    96  	}
    97  
    98  	if err := stopServices(u.cfg, u.out, u.ipComm, params.Force); err != nil {
    99  		return errs.Wrap(err, "Failed to stop services.")
   100  	}
   101  
   102  	if err := u.runUninstall(params); err != nil {
   103  		return errs.Wrap(err, "Could not complete uninstallation")
   104  	}
   105  
   106  	if err := events.WaitForEvents(5*time.Second, u.an.Close, logging.Close); err != nil {
   107  		return errs.Wrap(err, "Failed to wait for analytics and logging to close")
   108  	}
   109  
   110  	return nil
   111  }