mirror of
https://github.com/langgenius/dify-plugin-daemon.git
synced 2026-07-22 09:45:27 -04:00
99 lines
2.0 KiB
Go
99 lines
2.0 KiB
Go
package packager
|
|
|
|
import (
|
|
"archive/zip"
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/langgenius/dify-plugin-daemon/pkg/plugin_packager/decoder"
|
|
)
|
|
|
|
type Packager struct {
|
|
decoder decoder.PluginDecoder
|
|
manifest string // manifest file path
|
|
}
|
|
|
|
func NewPackager(decoder decoder.PluginDecoder) *Packager {
|
|
return &Packager{
|
|
decoder: decoder,
|
|
manifest: "manifest.yaml",
|
|
}
|
|
}
|
|
|
|
func (p *Packager) Pack(maxSize int64) ([]byte, error) {
|
|
err := p.Validate()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
zipBuffer := new(bytes.Buffer)
|
|
zipWriter := zip.NewWriter(zipBuffer)
|
|
|
|
totalSize := int64(0)
|
|
|
|
var files []FileInfoWithPath
|
|
|
|
err = p.decoder.Walk(func(filename, dir string) error {
|
|
fullPath := filepath.Join(dir, filename)
|
|
file, err := p.decoder.ReadFile(fullPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fileSize := int64(len(file))
|
|
files = append(files, FileInfoWithPath{Path: fullPath, Size: fileSize})
|
|
totalSize += fileSize
|
|
if totalSize > maxSize {
|
|
sort.Slice(files, func(i, j int) bool {
|
|
return files[i].Size > files[j].Size
|
|
})
|
|
fileTop5Info := ""
|
|
top := 5
|
|
if len(files) < 5 {
|
|
top = len(files)
|
|
}
|
|
for i := 0; i < top; i++ {
|
|
fileTop5Info += fmt.Sprintf("%d. name: %s, size: %d bytes\n", i+1, files[i].Path, files[i].Size)
|
|
}
|
|
errMsg := fmt.Sprintf("Plugin package size is too large. Please ensure the uncompressed size is less than %d bytes.\nPackaged file info:\n%s",
|
|
maxSize, fileTop5Info)
|
|
return errors.New(errMsg)
|
|
}
|
|
|
|
// ISSUES: Windows path separator is \, but zip requires /, to avoid this we just simply replace all \ with / for now
|
|
// TODO: find a better solution
|
|
fullPath = strings.ReplaceAll(fullPath, "\\", "/")
|
|
|
|
zipFile, err := zipWriter.Create(fullPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = zipFile.Write(file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = zipWriter.Close()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return zipBuffer.Bytes(), nil
|
|
}
|
|
|
|
type FileInfoWithPath struct {
|
|
Path string
|
|
Size int64
|
|
}
|