瀏覽代碼

feat: check package validation, add icon existence check

Yeuoly 8 月之前
父節點
當前提交
d02d6ead02

+ 3 - 0
internal/core/plugin_packager/decoder/decoder.go

@@ -54,4 +54,7 @@ type PluginDecoder interface {
 
 	// Checksum returns the checksum of the plugin
 	Checksum() (string, error)
+
+	// Check Assets valid
+	CheckAssetsValid() error
 }

+ 4 - 0
internal/core/plugin_packager/decoder/fs.go

@@ -186,3 +186,7 @@ func (d *FSPluginDecoder) Checksum() (string, error) {
 func (d *FSPluginDecoder) UniqueIdentity() (plugin_entities.PluginUniqueIdentifier, error) {
 	return d.PluginDecoderHelper.UniqueIdentity(d)
 }
+
+func (d *FSPluginDecoder) CheckAssetsValid() error {
+	return d.PluginDecoderHelper.CheckAssetsValid(d)
+}

+ 82 - 0
internal/core/plugin_packager/decoder/helper.go

@@ -302,3 +302,85 @@ func (p *PluginDecoderHelper) UniqueIdentity(decoder PluginDecoder) (plugin_enti
 
 	return plugin_entities.NewPluginUniqueIdentifier(fmt.Sprintf("%s@%s", identity, checksum))
 }
+
+func (p *PluginDecoderHelper) CheckAssetsValid(decoder PluginDecoder) error {
+	declaration, err := decoder.Manifest()
+	if err != nil {
+		return errors.Join(err, fmt.Errorf("failed to get manifest"))
+	}
+
+	assets, err := decoder.Assets()
+	if err != nil {
+		return errors.Join(err, fmt.Errorf("failed to get assets"))
+	}
+
+	if declaration.Model != nil {
+		if declaration.Model.IconSmall != nil {
+			if declaration.Model.IconSmall.EnUS != "" {
+				if _, ok := assets[declaration.Model.IconSmall.EnUS]; !ok {
+					return errors.Join(err, fmt.Errorf("model icon small en_US not found"))
+				}
+			}
+
+			if declaration.Model.IconSmall.ZhHans != "" {
+				if _, ok := assets[declaration.Model.IconSmall.ZhHans]; !ok {
+					return errors.Join(err, fmt.Errorf("model icon small zh_Hans not found"))
+				}
+			}
+
+			if declaration.Model.IconSmall.JaJp != "" {
+				if _, ok := assets[declaration.Model.IconSmall.JaJp]; !ok {
+					return errors.Join(err, fmt.Errorf("model icon small ja_JP not found"))
+				}
+			}
+
+			if declaration.Model.IconSmall.PtBr != "" {
+				if _, ok := assets[declaration.Model.IconSmall.PtBr]; !ok {
+					return errors.Join(err, fmt.Errorf("model icon small pt_BR not found"))
+				}
+			}
+		}
+
+		if declaration.Model.IconLarge != nil {
+			if declaration.Model.IconLarge.EnUS != "" {
+				if _, ok := assets[declaration.Model.IconLarge.EnUS]; !ok {
+					return errors.Join(err, fmt.Errorf("model icon large en_US not found"))
+				}
+			}
+
+			if declaration.Model.IconLarge.ZhHans != "" {
+				if _, ok := assets[declaration.Model.IconLarge.ZhHans]; !ok {
+					return errors.Join(err, fmt.Errorf("model icon large zh_Hans not found"))
+				}
+			}
+
+			if declaration.Model.IconLarge.JaJp != "" {
+				if _, ok := assets[declaration.Model.IconLarge.JaJp]; !ok {
+					return errors.Join(err, fmt.Errorf("model icon large ja_JP not found"))
+				}
+			}
+
+			if declaration.Model.IconLarge.PtBr != "" {
+				if _, ok := assets[declaration.Model.IconLarge.PtBr]; !ok {
+					return errors.Join(err, fmt.Errorf("model icon large pt_BR not found"))
+				}
+			}
+		}
+	}
+
+	if declaration.Tool != nil {
+		if declaration.Tool.Identity.Icon != "" {
+			if _, ok := assets[declaration.Tool.Identity.Icon]; !ok {
+				return errors.Join(err, fmt.Errorf("tool icon not found"))
+			}
+		}
+	}
+
+	if declaration.Icon != "" {
+		if _, ok := assets[declaration.Icon]; !ok {
+			return errors.Join(err, fmt.Errorf("plugin icon not found"))
+		}
+	}
+
+	return nil
+}

+ 4 - 0
internal/core/plugin_packager/decoder/zip.go

@@ -231,3 +231,7 @@ func (z *ZipPluginDecoder) ExtractTo(dst string) error {
 
 	return nil
 }
+
+func (z *ZipPluginDecoder) CheckAssetsValid() error {
+	return z.PluginDecoderHelper.CheckAssetsValid(z)
+}

+ 11 - 0
internal/core/plugin_packager/packager/validator.go

@@ -1,5 +1,10 @@
 package packager
 
+import (
+	"errors"
+	"fmt"
+)
+
 func (p *Packager) Validate() error {
 	// read manifest
 	_, err := p.fetchManifest()
@@ -7,5 +12,11 @@ func (p *Packager) Validate() error {
 		return err
 	}
 
+	// check assets valid
+	err = p.decoder.CheckAssetsValid()
+	if err != nil {
+		return errors.Join(err, fmt.Errorf("assets invalid"))
+	}
+
 	return nil
 }

+ 12 - 0
internal/core/plugin_packager/packager_test.go

@@ -165,6 +165,18 @@ func TestWrongSign(t *testing.T) {
 		return
 	}
 
+	// create _assets directory
+	if err := os.MkdirAll("temp/_assets", 0755); err != nil {
+		t.Errorf("failed to create _assets directory: %s", err.Error())
+		return
+	}
+
+	// create _assets/test.svg
+	if err := os.WriteFile("temp/_assets/test.svg", test_svg, 0644); err != nil {
+		t.Errorf("failed to write test.svg: %s", err.Error())
+		return
+	}
+
 	originDecoder, err := decoder.NewFSPluginDecoder("temp")
 	if err != nil {
 		t.Errorf("failed to create decoder: %s", err.Error())