126 lines
3.1 KiB
Go
126 lines
3.1 KiB
Go
//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
|
|
}
|