Skip to content

Commit

Permalink
feat: remap positive plugin assets
Browse files Browse the repository at this point in the history
  • Loading branch information
Yeuoly committed Sep 5, 2024
1 parent 4080255 commit de788d4
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 2 deletions.
27 changes: 25 additions & 2 deletions internal/core/plugin_manager/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,15 @@ func (p *PluginManager) handleNewPlugins(config *app.Config) {
for plugin := range p.loadNewPlugins(config.PluginStoragePath) {
var plugin_interface plugin_entities.PluginRuntimeInterface

// get assets
assets, err := plugin.Decoder.Assets()
if err != nil {
log.Error("get plugin assets error: %v", err)
continue
}

if config.Platform == app.PLATFORM_AWS_LAMBDA {
plugin_interface = &aws_manager.AWSPluginRuntime{
aws_plugin_runtime := &aws_manager.AWSPluginRuntime{
PluginRuntime: plugin.Runtime,
PositivePluginRuntime: positive_manager.PositivePluginRuntime{
BasicPluginRuntime: basic_manager.NewBasicPluginRuntime(p.mediaManager),
Expand All @@ -65,8 +72,16 @@ func (p *PluginManager) handleNewPlugins(config *app.Config) {
Decoder: plugin.Decoder,
},
}
if err := aws_plugin_runtime.RemapAssets(
&aws_plugin_runtime.Config,
assets,
); err != nil {
log.Error("remap plugin assets error: %v", err)
continue
}
plugin_interface = aws_plugin_runtime
} else if config.Platform == app.PLATFORM_LOCAL {
plugin_interface = &local_manager.LocalPluginRuntime{
local_plugin_runtime := &local_manager.LocalPluginRuntime{
PluginRuntime: plugin.Runtime,
PositivePluginRuntime: positive_manager.PositivePluginRuntime{
BasicPluginRuntime: basic_manager.NewBasicPluginRuntime(p.mediaManager),
Expand All @@ -75,6 +90,14 @@ func (p *PluginManager) handleNewPlugins(config *app.Config) {
Decoder: plugin.Decoder,
},
}
if err := local_plugin_runtime.RemapAssets(
&local_plugin_runtime.Config,
assets,
); err != nil {
log.Error("remap plugin assets error: %v", err)
continue
}
plugin_interface = local_plugin_runtime
} else {
log.Error("unsupported platform: %s for plugin: %s", config.Platform, plugin.Runtime.Config.Name)
continue
Expand Down
1 change: 1 addition & 0 deletions internal/core/plugin_packager/_assets/test.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions internal/core/plugin_packager/decoder/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"
"io/fs"
"strings"

"github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
"github.com/langgenius/dify-plugin-daemon/internal/utils/parser"
Expand All @@ -22,6 +23,14 @@ type PluginDecoder interface {
// ReadFile reads the entire contents of a file and returns it as a byte slice
ReadFile(filename string) ([]byte, error)

// ReadDir reads the contents of a directory and returns a slice of strings
// The strings are the filenames, it's a full path and directory will not be included
// It executes recursively
// Example:
// - dirname: "config"
// - return: ["config/settings.yaml", "config/default.yaml"]
ReadDir(dirname string) ([]string, error)

// Close releases any resources used by the decoder
Close() error

Expand All @@ -40,6 +49,9 @@ type PluginDecoder interface {

// Manifest returns the manifest of the plugin
Manifest() (plugin_entities.PluginDeclaration, error)

// Assets returns a map of assets, the key is the filename, the value is the content
Assets() (map[string][]byte, error)
}

type PluginDecoderHelper struct {
Expand Down Expand Up @@ -104,3 +116,23 @@ func (p *PluginDecoderHelper) Manifest(decoder PluginDecoder) (plugin_entities.P
p.pluginDeclaration = &dec
return dec, nil
}

func (p *PluginDecoderHelper) Assets(decoder PluginDecoder) (map[string][]byte, error) {
files, err := decoder.ReadDir("_assets")
if err != nil {
return nil, err
}

assets := make(map[string][]byte)
for _, file := range files {
content, err := decoder.ReadFile(file)
if err != nil {
return nil, err
}
// trim _assets
file, _ = strings.CutPrefix(file, "_assets/")
assets[file] = content
}

return assets, nil
}
28 changes: 28 additions & 0 deletions internal/core/plugin_packager/decoder/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,30 @@ func (d *FSPluginDecoder) ReadFile(filename string) ([]byte, error) {
return os.ReadFile(filepath.Join(d.root, filename))
}

func (d *FSPluginDecoder) ReadDir(dirname string) ([]string, error) {
var files []string
err := filepath.WalkDir(
filepath.Join(d.root, dirname),
func(path string, info fs.DirEntry, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
rel_path, err := filepath.Rel(d.root, path)
if err != nil {
return err
}
files = append(files, rel_path)
}
return nil
},
)
if err != nil {
return nil, err
}
return files, nil
}

func (d *FSPluginDecoder) FileReader(filename string) (io.ReadCloser, error) {
return os.Open(filepath.Join(d.root, filename))
}
Expand All @@ -109,3 +133,7 @@ func (d *FSPluginDecoder) CreateTime() (int64, error) {
func (d *FSPluginDecoder) Manifest() (plugin_entities.PluginDeclaration, error) {
return d.PluginDecoderHelper.Manifest(d)
}

func (d *FSPluginDecoder) Assets() (map[string][]byte, error) {
return d.PluginDecoderHelper.Assets(d)
}
22 changes: 22 additions & 0 deletions internal/core/plugin_packager/decoder/zip.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io"
"io/fs"
"path"
"strings"

"github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
"github.com/langgenius/dify-plugin-daemon/internal/utils/parser"
Expand Down Expand Up @@ -100,6 +101,23 @@ func (z *ZipPluginDecoder) ReadFile(filename string) ([]byte, error) {
return data.Bytes(), nil
}

func (z *ZipPluginDecoder) ReadDir(dirname string) ([]string, error) {
if z.reader == nil {
return nil, z.err
}

files := make([]string, 0)
dir_name_with_slash := strings.TrimSuffix(dirname, "/") + "/"

for _, file := range z.reader.File {
if strings.HasPrefix(file.Name, dir_name_with_slash) {
files = append(files, file.Name)
}
}

return files, nil
}

func (z *ZipPluginDecoder) FileReader(filename string) (io.ReadCloser, error) {
return z.reader.Open(filename)
}
Expand Down Expand Up @@ -165,3 +183,7 @@ func (z *ZipPluginDecoder) CreateTime() (int64, error) {
func (z *ZipPluginDecoder) Manifest() (plugin_entities.PluginDeclaration, error) {
return z.PluginDecoderHelper.Manifest(z)
}

func (z *ZipPluginDecoder) Assets() (map[string][]byte, error) {
return z.PluginDecoderHelper.Assets(z)
}
1 change: 1 addition & 0 deletions internal/core/plugin_packager/manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ version: 0.0.1
type: plugin
author: "Yeuoly"
name: "Neko"
icon: test.svg
label:
en_US: "Neko"
created_at: "2024-07-12T08:03:44.658609186Z"
Expand Down
37 changes: 37 additions & 0 deletions internal/core/plugin_packager/packager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ var manifest []byte
//go:embed neko.yaml
var neko []byte

//go:embed _assets/test.svg
var test_svg []byte

func TestPackagerAndVerifier(t *testing.T) {
// create a temp directory
os.RemoveAll("temp")
Expand All @@ -40,12 +43,34 @@ func TestPackagerAndVerifier(t *testing.T) {
return
}

if err := os.MkdirAll("temp/_assets", 0755); err != nil {
t.Errorf("failed to create _assets directory: %s", err.Error())
return
}

if err := os.WriteFile("temp/_assets/test.svg", test_svg, 0644); err != nil {
t.Errorf("failed to write test.svg: %s", err.Error())
return
}

origin_decoder, err := decoder.NewFSPluginDecoder("temp")
if err != nil {
t.Errorf("failed to create decoder: %s", err.Error())
return
}

// check assets
assets, err := origin_decoder.Assets()
if err != nil {
t.Errorf("failed to get assets: %s", err.Error())
return
}

if assets["test.svg"] == nil {
t.Errorf("should have test.svg asset, got %v", assets)
return
}

packager := packager.NewPackager(origin_decoder)

// pack
Expand All @@ -68,6 +93,18 @@ func TestPackagerAndVerifier(t *testing.T) {
return
}

// check assets
assets, err = signed_decoder.Assets()
if err != nil {
t.Errorf("failed to get assets: %s", err.Error())
return
}

if assets["test.svg"] == nil {
t.Errorf("should have test.svg asset, got %v", assets)
return
}

// verify
err = verifier.VerifyPlugin(signed_decoder)
if err != nil {
Expand Down

0 comments on commit de788d4

Please sign in to comment.