Add ability to uninstall a plugin

This commit is contained in:
tutman96 2025-01-05 19:43:10 +00:00
parent 5652e8f95a
commit 562f6c406c
5 changed files with 89 additions and 2 deletions

View File

@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"os"
"path"
"sync"
)
@ -58,3 +59,34 @@ func (d *PluginDatabase) Save() error {
return nil
}
// Find all extract directories that are not referenced in the Plugins map and remove them
func (d *PluginDatabase) CleanupExtractDirectories() error {
extractDirectories, err := os.ReadDir(pluginsExtractsFolder)
if err != nil {
return fmt.Errorf("failed to read extract directories: %v", err)
}
for _, extractDir := range extractDirectories {
found := false
for _, pluginInstall := range d.Plugins {
for _, extractedFolder := range pluginInstall.ExtractedVersions {
if extractDir.Name() == extractedFolder {
found = true
break
}
}
if found {
break
}
}
if !found {
if err := os.RemoveAll(path.Join(pluginsExtractsFolder, extractDir.Name())); err != nil {
return fmt.Errorf("failed to remove extract directory: %v", err)
}
}
}
return nil
}

View File

@ -168,7 +168,7 @@ func RpcPluginList() ([]PluginStatus, error) {
return plugins, nil
}
func RpcUpdateConfig(name string, enabled bool) (*PluginStatus, error) {
func RpcPluginUpdateConfig(name string, enabled bool) (*PluginStatus, error) {
pluginInstall, ok := pluginDatabase.Plugins[name]
if !ok {
return nil, fmt.Errorf("plugin not found: %s", name)
@ -193,6 +193,32 @@ func RpcUpdateConfig(name string, enabled bool) (*PluginStatus, error) {
return status, nil
}
func RpcPluginUninstall(name string) error {
pluginInstall, ok := pluginDatabase.Plugins[name]
if !ok {
return fmt.Errorf("plugin not found: %s", name)
}
pluginInstall.Enabled = false
err := pluginInstall.ReconcileSubprocess()
if err != nil {
return fmt.Errorf("failed to stop plugin %s: %v", name, err)
}
delete(pluginDatabase.Plugins, name)
if err := pluginDatabase.Save(); err != nil {
return fmt.Errorf("failed to save plugin database: %v", err)
}
err = pluginDatabase.CleanupExtractDirectories()
if err != nil {
return fmt.Errorf("failed to cleanup extract directories: %v", err)
}
return nil
}
func readManifest(extractFolder string) (*PluginManifest, error) {
manifestPath := path.Join(extractFolder, "manifest.json")
manifestFile, err := os.Open(manifestPath)

View File

@ -559,5 +559,6 @@ var rpcHandlers = map[string]RPCHandler{
"pluginExtract": {Func: plugin.RpcPluginExtract, Params: []string{"filename"}},
"pluginInstall": {Func: plugin.RpcPluginInstall, Params: []string{"name", "version"}},
"pluginList": {Func: plugin.RpcPluginList},
"pluginUpdateConfig": {Func: plugin.RpcUpdateConfig, Params: []string{"name", "enabled"}},
"pluginUpdateConfig": {Func: plugin.RpcPluginUpdateConfig, Params: []string{"name", "enabled"}},
"pluginUninstall": {Func: plugin.RpcPluginUninstall, Params: []string{"name"}},
}

View File

@ -46,6 +46,24 @@ function Dialog({ plugin, setOpen }: { plugin: PluginStatus | null, setOpen: (op
setLoading(true);
send("pluginUpdateConfig", { name: plugin.name, enabled }, resp => {
if ("error" in resp) {
setLoading(false);
setError(resp.error.message);
return
}
setOpen(false);
});
}, [send, plugin, setOpen])
const uninstallPlugin = useCallback(() => {
if (!plugin) return;
if (!window.confirm("Are you sure you want to uninstall this plugin? This will not delete any data.")) {
return;
}
setLoading(true);
send("pluginUninstall", { name: plugin.name }, resp => {
if ("error" in resp) {
setLoading(false);
setError(resp.error.message);
return
}
@ -104,6 +122,15 @@ function Dialog({ plugin, setOpen }: { plugin: PluginStatus | null, setOpen: (op
animationDelay: "0.1s",
}}
>
<div className="flex items-center w-full space-x-2">
<Button
size="MD"
theme="blank"
text="Uninstall Plugin"
disabled={loading}
onClick={uninstallPlugin}
/>
</div>
<div className="flex justify-end w-full space-x-2">
<Button
size="MD"

View File

@ -629,6 +629,7 @@ function InstallPluginView({
size="MD"
theme="primary"
text="Install"
disabled={!manifest || installing}
onClick={handleInstall}
/>
</div>