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 }