Skip to content

Commit

Permalink
Merge pull request #14 from MTVersionManager/removePluginCmd
Browse files Browse the repository at this point in the history
Add remove plugin command
  • Loading branch information
leomick authored Feb 9, 2025
2 parents da2142c + 7b8d0c1 commit 8c4f30c
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 9 deletions.
1 change: 1 addition & 0 deletions cmd/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var pluginCmd = &cobra.Command{
func init() {
rootCmd.AddCommand(pluginCmd)
pluginCmd.AddCommand(plugincmds.InstallCmd)
pluginCmd.AddCommand(plugincmds.RemoveCmd)
// Here you will define your flags and configuration settings.

// Cobra supports Persistent Flags which will work for this command
Expand Down
7 changes: 4 additions & 3 deletions cmd/plugincmds/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (
"path/filepath"
"runtime"

"github.com/MTVersionManager/mtvm/components/fatalHandler"

"github.com/MTVersionManager/mtvm/components/downloader"
"github.com/MTVersionManager/mtvm/components/fatalhandler"
"github.com/MTVersionManager/mtvm/plugin"
"github.com/MTVersionManager/mtvm/shared"
"github.com/Masterminds/semver/v3"
Expand All @@ -21,7 +22,7 @@ import (
type installModel struct {
downloader downloader.Model
pluginInfo pluginDownloadInfo
errorHandler fatalhandler.Model
errorHandler fatalHandler.Model
versionInstalled bool
step int
metadataUrl string
Expand Down Expand Up @@ -192,7 +193,7 @@ var InstallCmd = &cobra.Command{
fmt.Printf("Alas, there's been an error: %v", err)
} else {
if model, ok := model.(installModel); ok {
fatalhandler.Handle(model.errorHandler)
fatalHandler.Handle(model.errorHandler)
} else {
log.Fatal("Unexpected model type")
}
Expand Down
94 changes: 94 additions & 0 deletions cmd/plugincmds/remove.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package plugincmds

import (
"fmt"

"github.com/MTVersionManager/mtvm/components/fatalHandler"
"github.com/MTVersionManager/mtvm/plugin"
"github.com/MTVersionManager/mtvm/shared"
"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/log"
"github.com/spf13/cobra"
)

const (
StatusNone = iota
StatusDone
StatusNotFound
)

type removeModel struct {
pluginName string
spinner spinner.Model
fileStatus int
entryStatus int
errorHandler fatalHandler.Model
}

func initialRemoveModel(pluginName string) removeModel {
spin := spinner.New()
spin.Spinner = spinner.Dot
return removeModel{
pluginName: pluginName,
spinner: spin,
}
}

func (m removeModel) Init() tea.Cmd {
return tea.Batch(m.spinner.Tick, plugin.RemoveEntryCmd(m.pluginName), plugin.RemoveCmd(m.pluginName))
}

func (m removeModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case error:
m.errorHandler, cmd = m.errorHandler.Update(msg)
return m, cmd
case shared.SuccessMsg:
if string(msg) == "RemoveEntry" {
m.entryStatus = StatusDone
} else if string(msg) == "Remove" {
m.fileStatus = StatusDone
}
case plugin.NotFoundMsg:
if msg.Source == "RemoveEntry" {
m.entryStatus = StatusNotFound
} else if msg.Source == "Remove" {
m.fileStatus = StatusNotFound
}
}
if m.entryStatus != StatusNone && m.fileStatus != StatusNone {
return m, tea.Quit
}
m.spinner, cmd = m.spinner.Update(msg)
return m, cmd
}

func (m removeModel) View() string {
if m.fileStatus == StatusNone && m.entryStatus == StatusNone {
return fmt.Sprintf("%v Removing %v...\n", m.spinner.View(), m.pluginName)
}
if m.fileStatus == StatusNotFound && m.entryStatus == StatusNotFound {
return fmt.Sprintf("%v No changes were made as %v is not installed\n", shared.CheckMark, m.pluginName)
}
return fmt.Sprintf("%v Successfully removed %v\n", shared.CheckMark, m.pluginName)
}

var RemoveCmd = &cobra.Command{
Use: "remove",
Short: "Remove a plugin",
Long: `Remove the plugin with the name specified`,
Args: cobra.ExactArgs(1),
Aliases: []string{"r", "rm"},
Run: func(cmd *cobra.Command, args []string) {
p := tea.NewProgram(initialRemoveModel(args[0]))
if model, err := p.Run(); err != nil {
log.Fatal(err)
} else {
if model, ok := model.(removeModel); ok {
fatalHandler.Handle(model.errorHandler)
}
}
},
}
2 changes: 1 addition & 1 deletion cmd/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ var removeCmd = &cobra.Command{
For example:
"mtvm remove go 1.23.3" removes go version 1.23.3`,
Args: cobra.ExactArgs(2),
Aliases: []string{"rm", "r"},
Aliases: []string{"r", "rm"},
Run: func(cmd *cobra.Command, args []string) {
plugin, err := shared.LoadPlugin(args[0])
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package fatalhandler
package fatalHandler

import (
tea "github.com/charmbracelet/bubbletea"
Expand Down
41 changes: 38 additions & 3 deletions plugin/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,46 @@ func InstalledVersionCmd(pluginName string) tea.Cmd {
return func() tea.Msg {
version, err := InstalledVersion(pluginName)
if err != nil {
if !errors.Is(err, ErrNotFound) {
return err
if errors.Is(err, ErrNotFound) {
return NotFoundMsg{
PluginName: pluginName,
Source: "InstalledVersion",
}
}
return NotFoundMsg(pluginName)
return err
}
return VersionMsg(version)
}
}

func RemoveEntryCmd(pluginName string) tea.Cmd {
return func() tea.Msg {
err := RemoveEntry(pluginName)
if err != nil {
if errors.Is(err, ErrNotFound) {
return NotFoundMsg{
PluginName: pluginName,
Source: "RemoveEntry",
}
}
return err
}
return shared.SuccessMsg("RemoveEntry")
}
}

func RemoveCmd(pluginName string) tea.Cmd {
return func() tea.Msg {
err := Remove(pluginName)
if err != nil {
if errors.Is(err, ErrNotFound) {
return NotFoundMsg{
PluginName: pluginName,
Source: "Remove",
}
}
return err
}
return shared.SuccessMsg("Remove")
}
}
5 changes: 4 additions & 1 deletion plugin/types.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package plugin

// NotFoundMsg contains the name of the plugin that is not found
type NotFoundMsg string
type NotFoundMsg struct {
PluginName string
Source string
}

// VersionMsg contains the version that was found
type VersionMsg string
Expand Down
50 changes: 50 additions & 0 deletions plugin/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"os"
"path/filepath"

"github.com/MTVersionManager/mtvm/shared"

"github.com/MTVersionManager/mtvm/config"
)

Expand Down Expand Up @@ -95,3 +97,51 @@ func GetEntries() ([]Entry, error) {
}
return entries, nil
}

func RemoveEntry(pluginName string) error {
configDir, err := config.GetConfigDir()
if err != nil {
return err
}
data, err := os.ReadFile(filepath.Join(configDir, "plugins.json"))
if err != nil {
if os.IsNotExist(err) {
return ErrNotFound
}
return err
}
var entries []Entry
err = json.Unmarshal(data, &entries)
if err != nil {
return err
}
if len(entries) == 0 {
return ErrNotFound
}
removed := make([]Entry, 0, len(entries)-1)
for _, v := range entries {
if v.Name != pluginName {
removed = append(removed, v)
}
}
if len(removed) == len(entries) {
return ErrNotFound
}
data, err = json.MarshalIndent(removed, "", " ")
if err != nil {
return err
}
return os.WriteFile(filepath.Join(configDir, "plugins.json"), data, 0o666)
}

func Remove(pluginName string) error {
configDir, err := config.GetConfigDir()
if err != nil {
return err
}
err = os.Remove(filepath.Join(configDir, "plugins", pluginName+shared.LibraryExtension))
if os.IsNotExist(err) {
return ErrNotFound
}
return err
}

0 comments on commit 8c4f30c

Please sign in to comment.