//go:build mage // +build mage package main import ( "fmt" "io/ioutil" "os" "path/filepath" "unicode" "unicode/utf8" "github.com/magefile/mage/mg" "github.com/magefile/mage/sh" "github.com/xeipuuv/gojsonschema" ) const ( zipName = "DigitalStorageTweaks.zip" contentDir = "./ContentLib" pluginFile = "./DigitalStorageTweaks.uplugin" ) // Default target var Default = Build // Build runs the full pipeline func Build() { mg.SerialDeps(Validate, Package) } // Package creates the distribution zip func Package() error { fmt.Println("Packaging files...") // Create target directories for _, dir := range []string{"Windows", "WindowsServer", "LinuxServer"} { if err := os.MkdirAll(dir, 0755); err != nil { return fmt.Errorf("creating %s: %w", dir, err) } if err := sh.Run("cp", "-r", contentDir, pluginFile, dir+"/"); err != nil { return fmt.Errorf("copying to %s: %w", dir, err) } } // Create zip if err := sh.Run("7z", "a", "-r", zipName, "Windows/", "LinuxServer/", "WindowsServer/"); err != nil { return fmt.Errorf("creating zip: %w", err) } // Clean temp dirs return Clean("Windows", "WindowsServer", "LinuxServer") } // Validate checks all content files func Validate() error { fmt.Println("Validating files...") // Check plugin file if err := checkFile(pluginFile); err != nil { return fmt.Errorf("plugin file: %w", err) } // Check content directory return filepath.Walk(contentDir, func(path string, info os.FileInfo, err error) error { if err != nil || info.IsDir() { return err } return checkFile(path) }) } func checkFile(path string) error { // Skip binary files switch filepath.Ext(path) { case ".png", ".jpg", ".jpeg", ".bmp", ".gif", ".dds", ".tga", ".psd", ".fbx", ".uasset", ".umap": return nil case ".json": return validateJSON(path) default: return validateEncoding(path) } } func validateJSON(path string) error { schemaLoader := gojsonschema.NewReferenceLoader("https://raw.githubusercontent.com/budak7273/ContentLib_Documentation/main/JsonSchemas/CL_Recipe.json") documentLoader := gojsonschema.NewReferenceLoader("file:///" + filepath.ToSlash(path)) result, err := gojsonschema.Validate(schemaLoader, documentLoader) if err != nil { return fmt.Errorf("schema validation failed: %w", err) } if !result.Valid() { return fmt.Errorf("invalid JSON schema: %v", result.Errors()) } return nil } func validateEncoding(path string) error { content, err := ioutil.ReadFile(path) if err != nil { return err } // Check for non-ASCII for i := 0; i < len(content); i++ { if content[i] > unicode.MaxASCII { r, _ := utf8.DecodeRune(content[i:]) return fmt.Errorf("non-ASCII character %U at position %d", r, i) } } return nil } // Clean removes all build artifacts func Clean(list ...string) error { fmt.Println("Cleaning up...") for _, f := range list { if err := os.RemoveAll(f); err != nil { return fmt.Errorf("failed to remove %s: %w", f, err) } } return nil }