packager.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package packager
  2. import (
  3. "archive/zip"
  4. "bytes"
  5. "errors"
  6. "path/filepath"
  7. "strconv"
  8. "strings"
  9. "github.com/langgenius/dify-plugin-daemon/internal/core/plugin_packager/decoder"
  10. )
  11. type Packager struct {
  12. decoder decoder.PluginDecoder
  13. manifest string // manifest file path
  14. }
  15. func NewPackager(decoder decoder.PluginDecoder) *Packager {
  16. return &Packager{
  17. decoder: decoder,
  18. manifest: "manifest.yaml",
  19. }
  20. }
  21. func (p *Packager) Pack(maxSize int64) ([]byte, error) {
  22. err := p.Validate()
  23. if err != nil {
  24. return nil, err
  25. }
  26. zipBuffer := new(bytes.Buffer)
  27. zipWriter := zip.NewWriter(zipBuffer)
  28. totalSize := int64(0)
  29. err = p.decoder.Walk(func(filename, dir string) error {
  30. fullPath := filepath.Join(dir, filename)
  31. file, err := p.decoder.ReadFile(fullPath)
  32. if err != nil {
  33. return err
  34. }
  35. totalSize += int64(len(file))
  36. if totalSize > maxSize {
  37. return errors.New("plugin package size is too large, please ensure the uncompressed size is less than " + strconv.FormatInt(maxSize, 10) + " bytes")
  38. }
  39. // ISSUES: Windows path separator is \, but zip requires /, to avoid this we just simply replace all \ with / for now
  40. // TODO: find a better solution
  41. fullPath = strings.ReplaceAll(fullPath, "\\", "/")
  42. zipFile, err := zipWriter.Create(fullPath)
  43. if err != nil {
  44. return err
  45. }
  46. _, err = zipFile.Write(file)
  47. if err != nil {
  48. return err
  49. }
  50. return nil
  51. })
  52. if err != nil {
  53. return nil, err
  54. }
  55. err = zipWriter.Close()
  56. if err != nil {
  57. return nil, err
  58. }
  59. return zipBuffer.Bytes(), nil
  60. }