diff --git a/experimental/submission.go b/experimental/submission.go index 5a86e15..48039df 100644 --- a/experimental/submission.go +++ b/experimental/submission.go @@ -61,25 +61,45 @@ func SubmitPackage(authKey string, metadata PackageSubmissionMetadata) (*Package return &res, nil } -func ValidateReadme(data []byte) (bool, error) { +// Simply checks the input data is valid markdown and doesn't exceed the max size. +// +// To this method does NOT call the API but rather simulates what it would do, avoiding an unnecessary call. +func ValidateReadme(data []byte) (valid bool, errs []error, err error) { if !utf8.Valid(data) { - return false, errors.New("error parsing readme: file is not UTF-8 compatible") + Add(&errs, "error parsing readme: file is not UTF-8 compatible") } bom := []byte{0xEF, 0xBB, 0xBF} if bytes.HasPrefix(data, bom) { - return false, fmt.Errorf("readme cannot begin with a UTF-8 BOM") + Add(&errs, "readme cannot begin with a UTF-8 BOM") } str := string(data) if len(str) > MAX_MARKDOWN_SIZE { - return false, fmt.Errorf("readme is too large: max file size is 100kb") + Add(&errs, fmt.Sprintf("readme is too large: max file size is %v", util.PrettyByteSize(MAX_MARKDOWN_SIZE))) } - return true, nil + return true, errs, nil } -func ValidateManifest(author string, data []byte) (valid bool, errs []string, err error) { +// Unmarshals the data into ManifestMetadata and checks all properties pass their requirements, +// reporting any that fail to the resulting 'errs' variable. The last variable 'err' indicates whether +// the unmarshal failed, before any properties are able to be checked. +// +// To this method does NOT call the API but rather simulates what it would do, avoiding an unnecessary call. +// +// # Example usage: +// +// valid, errs, err := ValidateManifest("Owen3H", manifestData) +// if err != nil { +// fmt.Println(err) +// return +// } +// +// if !valid { +// fmt.Println(errs) +// } +func ValidateManifest(author string, data []byte) (valid bool, errs []error, err error) { var manifest ManifestMetadata err = json.Unmarshal(data, &manifest) @@ -168,11 +188,11 @@ func ValidateIcon(data []byte) (bool, error) { return true, nil } -func Add(arr *[]string, errStr string) { - *arr = append(*arr, errStr) +func Add(arr *[]error, errStr string) { + *arr = append(*arr, errors.New(errStr)) } -func AddIfEmpty(arr *[]string, str *string, errStr string) bool { +func AddIfEmpty(arr *[]error, str *string, errStr string) bool { empty := *str == "" || str == nil if empty { Add(arr, errStr) @@ -181,9 +201,11 @@ func AddIfEmpty(arr *[]string, str *string, errStr string) bool { return empty } -func AddIfInvalid(arr *[]string, str *string, errStr string) { +func AddIfInvalid(arr *[]error, str *string, errStr string) bool { matched, _ := regexp.MatchString(`^[a-zA-Z0-9_]+$`, *str) if !matched { Add(arr, errStr) } + + return matched } diff --git a/tests/exp/submission_test.go b/tests/exp/submission_test.go index 31c3f68..8d7fbd3 100644 --- a/tests/exp/submission_test.go +++ b/tests/exp/submission_test.go @@ -6,10 +6,10 @@ import ( "testing" TSGO "github.com/the-egg-corp/thundergo/experimental" - "github.com/the-egg-corp/thundergo/util" ) const iconPath = "../test-pkg/icon.png.jpg" +const readmePath = "../test-pkg/README.md" const manifestPath = "../test-pkg/manifest.json" func TestValidateIcon(t *testing.T) { @@ -25,13 +25,37 @@ func TestValidateIcon(t *testing.T) { t.Fatal(err.Error()) } - util.PrettyPrint(valid) + fmt.Println(valid) } -func TestValidateManifest(t *testing.T) { +func TestValidateReadme(t *testing.T) { t.Skip() - var errs []string + data, err := os.ReadFile(readmePath) + if err != nil { + t.Fatal(err.Error()) + } + + valid, errs, err := TSGO.ValidateReadme(data) + if err != nil { + t.Fatal(err) + } + + fmt.Println("Valid: ", valid) + + if len(errs) > 0 { + fmt.Println(errs) + + if valid { + t.Fatal("errors were returned, but readme is still valid") + } + + return + } +} + +func TestValidateManifest(t *testing.T) { + t.Skip() data, err := os.ReadFile(manifestPath) if err != nil { @@ -40,13 +64,13 @@ func TestValidateManifest(t *testing.T) { valid, errs, err := TSGO.ValidateManifest("Owen3H", data) if err != nil { - t.Fatal(err.Error()) + t.Fatal(err) } fmt.Println("Valid: ", valid) if len(errs) > 0 { - util.PrettyPrint(errs) + fmt.Println(errs) if valid { t.Fatal("errors were returned, but manifest is still valid") diff --git a/util/funcs.go b/util/funcs.go index 006e4c4..60e612f 100644 --- a/util/funcs.go +++ b/util/funcs.go @@ -1,6 +1,7 @@ package util import ( + "fmt" "reflect" "regexp" "strings" @@ -82,3 +83,19 @@ func CheckSemVer(version string) (bool, error) { return lo.Ternary(err == nil, matched, false), lo.Ternary(err == nil, nil, err) } + +// Yoinked from: https://yourbasic.org/golang/formatting-byte-size-to-human-readable-format/ +func PrettyByteSize(amt int64) string { + const unit = 1000 + if amt < unit { + return fmt.Sprintf("%d B", amt) + } + + div, exp := int64(unit), 0 + for n := amt / unit; n >= unit; n /= unit { + div *= unit + exp++ + } + + return fmt.Sprintf("%.0f %cB", float64(amt)/float64(div), "kMGTPE"[exp]) +}