This commit is contained in:
Melody Becker 2024-11-07 16:27:46 +01:00
parent a8abfb2219
commit 25243b3a9d
3 changed files with 113 additions and 5 deletions

View file

@ -0,0 +1,103 @@
/*
Tool for auto-generating API helper functions in regards to roles
*/
package main
import (
"flag"
"fmt"
"io"
"os"
"regexp"
"strings"
"gitlab.com/mstarongitlab/goutils/sliceutils"
)
var findRoleStructRegex = regexp.MustCompile(`type Role struct \{([\s\S]+)\}\n\n/\*`)
var (
flagInputFile = flag.String("input", "", "Specify the input file. If empty, read from stdin")
flagOutputFile = flag.String(
"output",
"",
"Specify the output file. If empty, writes to stdout",
)
)
func main() {
flag.Parse()
var input io.Reader
var output io.Writer
if *flagInputFile == "" {
input = os.Stdin
} else {
file, err := os.Open(*flagInputFile)
if err != nil {
panic(err)
}
defer file.Close()
input = file
}
if *flagOutputFile == "" {
output = os.Stdout
} else {
file, err := os.Create(*flagOutputFile)
if err != nil {
panic(err)
}
defer file.Close()
output = file
}
data, err := io.ReadAll(input)
if err != nil {
panic(err)
}
if !findRoleStructRegex.Match(data) {
panic("Input doesn't contain role struct")
}
content := findRoleStructRegex.FindStringSubmatch(string(data))[1]
lines := strings.Split(content, "\n")
lines = sliceutils.Map(lines, func(t string) string { return strings.TrimSpace(t) })
importantLines := sliceutils.Filter(lines, func(t string) bool {
if strings.HasPrefix(t, "//") {
return false
}
if strings.Contains(t, "gorm.Model") {
return false
}
data := sliceutils.Filter(strings.Split(t, " "), func(t string) bool { return t != "" })
if len(data) < 2 {
return false
}
if !strings.HasPrefix(data[1], "*") && !strings.HasPrefix(data[1], "[]") {
return false
}
return true
})
nameTypeMap := map[string]string{}
for _, line := range importantLines {
parts := sliceutils.Filter(strings.Split(line, " "), func(t string) bool { return t != "" })
nameTypeMap[parts[0]] = parts[1]
}
pkgString, _, _ := strings.Cut(string(data), "\n")
outBuilder := strings.Builder{}
outBuilder.WriteString(`// Code generated by cmd/RolesApiConverter DO NOT EDIT.
// If you need to refresh the content, run go generate again
`)
outBuilder.WriteString(pkgString + "\n\n")
outBuilder.WriteString("func convertStorageRoleToApiRole(r storage.Role) linstromRole {\n")
outBuilder.WriteString("return linstromRole{")
outBuilder.WriteString("Id:r.ID,CreatedAt:r.CreatedAt,UpdatedAt:&r.UpdatedAt,Name:r.Name,")
outBuilder.WriteString("Priority:r.Priority,IsUserRole:r.IsUserRole,IsBuiltIn:r.IsBuiltIn,")
for k := range nameTypeMap {
outBuilder.WriteString(fmt.Sprintf("%s:r.%s,", k, k))
}
outBuilder.WriteString("}\n}\n")
fmt.Fprint(output, outBuilder.String())
}

View file

@ -1,3 +1,12 @@
/*
Tool for generating helper functions for storage.Role structs inside of the storage package
It generates the following functions:
- CollapseRolesIntoOne: Collapse a list of roles into one singular role. Each value will be set to the
value of the role with the highest priority
- RoleDeepCopy: Copy a role, including all arrays. Every value will be copied too
- CompareRoles: Compare two roles. Returns true only if all fields are equal
(if one of the fields is nil, that field is seen as equal)
*/
package main
import (

View file

@ -6,10 +6,6 @@ import "time"
var (
_ = linstromNote{}
_ = linstromOriginServer{}
_ = linstromMediaMetadata{}
_ = linstromAccount{}
_ = linstromCustomAccountField{}
_ = linstromRole{}
)
@ -108,7 +104,7 @@ type linstromRole struct {
// If two roles have the same priority, the order is undetermined and may be random
// Default priority for new roles is 1 to always overwrite default user
// And full admin has max priority possible
Priority uint `jsonapi:"attr,priority"`
Priority uint32 `jsonapi:"attr,priority"`
// Whether this role is for a for a single user only (like custom, per user permissions in Discord)
// If yes, Name will be the id of the user in question
IsUserRole bool `jsonapi:"attr,is-user-role"`