Skip to content

Commit

Permalink
Add plugin support to the CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
wkalt committed May 26, 2024
1 parent 637dbc1 commit f39bdf7
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 0 deletions.
28 changes: 28 additions & 0 deletions client/dp3/cmd/install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package cmd

import (
"path"

"github.com/spf13/cobra"
"github.com/wkalt/dp3/client/dp3/util"
)

var installCmd = &cobra.Command{
Use: "install [name] [filepath]",
Short: "Install a plugin from a location on disk.",
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 2 {
bailf(cmd.UsageString())
}
pluginName := args[0]
pluginLocation := args[1]
pluginDir := path.Join(configDir(), "plugins", pluginName)
checkErr(util.EnsureDirectoryExists(pluginDir))
_, filename := path.Split(pluginLocation)
checkErr(util.Copy(pluginLocation, path.Join(pluginDir, filename)))
},
}

func init() {
pluginCmd.AddCommand(installCmd)
}
15 changes: 15 additions & 0 deletions client/dp3/cmd/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cmd

import (
"github.com/spf13/cobra"
)

var pluginCmd = &cobra.Command{
Use: "plugin",
Short: "Manage CLI plugins",
Run: func(cmd *cobra.Command, args []string) {},
}

func init() {
rootCmd.AddCommand(pluginCmd)
}
48 changes: 48 additions & 0 deletions client/dp3/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package cmd
import (
"fmt"
"os"
"path"
"path/filepath"
"plugin"

"github.com/spf13/cobra"
)
Expand All @@ -26,6 +29,51 @@ func bailf(format string, args ...interface{}) {
os.Exit(1)
}

func checkErr(err error) {
if err != nil {
bailf("error: %v", err)
}
}

func configDir() string {
home, err := os.UserHomeDir()
checkErr(err)
return path.Join(home, ".dp3")
}

func loadPlugins() {
confdir := configDir()
plugindir := filepath.Join(confdir, "plugins")
// if the directory doesn't exist, there's nothing to load.
if _, err := os.Stat(plugindir); os.IsNotExist(err) {
return
}

checkErr(filepath.WalkDir(plugindir, func(path string, info os.DirEntry, err error) error {
checkErr(err)
if info.IsDir() {
return nil
}
if filepath.Ext(info.Name()) != ".so" {
return nil
}
plug, err := plugin.Open(path)
checkErr(err)

sym, err := plug.Lookup("PluginCmd")
checkErr(err)

cmd, ok := sym.(**cobra.Command)
if !ok {
bailf("plugin %s does not export a *cobra.Command: %T", path, sym)
}
rootCmd.AddCommand(*cmd)
return nil
}))

}

func init() {
loadPlugins()
rootCmd.PersistentFlags().StringVarP(&serverURL, "server-url", "", "http://localhost:8089", "server-url")
}
26 changes: 26 additions & 0 deletions client/dp3/util/util.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package util

import (
"io"
"os"
)

Expand All @@ -11,3 +12,28 @@ func StdoutRedirected() bool {
}
return false
}

// EnsureDirectoryExists creates a directory if it does not exist.
func EnsureDirectoryExists(dir string) error {
if _, err := os.Stat(dir); os.IsNotExist(err) {
return os.MkdirAll(dir, 0755)
}
return nil
}

func Copy(src, dst string) error {
s, err := os.Open(src)
if err != nil {
return err
}
defer s.Close()

d, err := os.Create(dst)
if err != nil {
return err
}
defer d.Close()

_, err = io.Copy(d, s)
return err
}

0 comments on commit f39bdf7

Please sign in to comment.