auto detect unique keys in protobuf file

This commit is contained in:
Jeff Carr 2024-11-30 15:06:57 -06:00
parent d2112f954d
commit 3a4e0c1046
4 changed files with 95 additions and 9 deletions

25
main.go
View File

@ -4,6 +4,7 @@
package main package main
import ( import (
"errors"
"os" "os"
"strings" "strings"
@ -21,6 +22,8 @@ var BUILDTIME string
var sortmap map[string]string var sortmap map[string]string
var forge *forgepb.Forge // forgepb figures out how to run protoc correctly if it's needed var forge *forgepb.Forge // forgepb figures out how to run protoc correctly if it's needed
var marshalKeys []string
var uniqueKeys []string
func main() { func main() {
pp := arg.MustParse(&argv) pp := arg.MustParse(&argv)
@ -90,6 +93,12 @@ func main() {
os.Exit(0) os.Exit(0)
} }
// parse sort & marshal options from the .proto file
if err := findAutogenpb(sortmap); err != nil {
log.Info("autogenpb parse error:", err)
os.Exit(-1)
}
// try to make foo.pb.go with protoc if it's not here // try to make foo.pb.go with protoc if it's not here
sortmap["protoc"] = protobase + ".pb.go" sortmap["protoc"] = protobase + ".pb.go"
if !shell.Exists(sortmap["protoc"]) { if !shell.Exists(sortmap["protoc"]) {
@ -103,7 +112,7 @@ func main() {
// exit here // exit here
if !shell.Exists(sortmap["protoc"]) { if !shell.Exists(sortmap["protoc"]) {
log.Info("protoc build error.", sortmap["protoc"], "failed to be created with protoc and proto-gen-go") log.Info("protoc build error.", sortmap["protoc"], "failed to be created with protoc and proto-gen-go")
os.Exit(-1) badExit(errors.New("failed to be created with protoc and proto-gen-go"))
} }
// add mutex // add mutex
@ -118,14 +127,28 @@ func main() {
if argv.NoSort { if argv.NoSort {
log.Info("not making sort.pb.go file (--no-sort == true)") log.Info("not making sort.pb.go file (--no-sort == true)")
} else { } else {
if len(uniqueKeys) != 0 {
}
makeSortfile() makeSortfile()
} }
if argv.NoMarshal { if argv.NoMarshal {
log.Info("not making marshal.pb.go file (--no-marshal == true)") log.Info("not making marshal.pb.go file (--no-marshal == true)")
} else { } else {
if len(marshalKeys) != 0 {
}
// make the foo.marshal.pb.go file // make the foo.marshal.pb.go file
marshal(sortmap) marshal(sortmap)
} }
} }
func okExit(s string) {
log.Info("autogenpb ok", s)
os.Exit(0)
}
func badExit(err error) {
log.Info("autogenpb error:", err)
os.Exit(-1)
}

View File

@ -28,13 +28,15 @@ func marshal(names map[string]string) {
fmt.Fprintln(w, ")") fmt.Fprintln(w, ")")
fmt.Fprintln(w, "") fmt.Fprintln(w, "")
if len(argv.Marshal) == 0 { for _, v := range marshalKeys {
marshalThing(w, names["Base"]) log.Info("found marshal key in .proto", v)
marshalThing(w, names["Bases"]) marshalThing(w, v)
} else { }
for _, v := range argv.Marshal {
marshalThing(w, v) // marshalThing(w, names["Base"])
} // marshalThing(w, names["Bases"])
for _, v := range argv.Marshal {
marshalThing(w, v)
} }
} }

44
parseProtoFile.go Normal file
View File

@ -0,0 +1,44 @@
package main
// auto run protoc with the correct args
import (
"os"
"strings"
"go.wit.com/log"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
// finds autogenpb:marshal and autogenpb:unique in the .proto file
//
// adds fields to []marshal and []unique
func findAutogenpb(names map[string]string) error {
log.Info("starting findAutogenpb() on", names["protofile"])
// read in the .proto file
data, err := os.ReadFile(names["protofile"])
if err != nil {
// log.Info("open config file :", err)
return err
}
// look for included proto files
lines := strings.Split(string(data), "\n")
for _, line := range lines {
// log.Info("line:", line)
parts := strings.Fields(line)
if strings.Contains(line, "autogenpb:marshal") {
newm := parts[1]
log.Info("found marshal", newm)
marshalKeys = append(marshalKeys, newm)
}
if strings.Contains(line, "autogenpb:unique") {
newu := parts[1]
newu = cases.Title(language.English, cases.NoLower).String(newu)
log.Info("found unique field", newu)
uniqueKeys = append(uniqueKeys, newu)
}
}
return nil
}

19
sort.go
View File

@ -5,6 +5,8 @@ import (
"io" "io"
"os" "os"
"strings" "strings"
"go.wit.com/log"
) )
func makeSortfile() { func makeSortfile() {
@ -22,6 +24,21 @@ func makeSortfile() {
iterAppend(f, sortmap) // Append() enforce unique key argv.Append iterAppend(f, sortmap) // Append() enforce unique key argv.Append
} }
for _, s := range uniqueKeys {
log.Info("found unique key in .proto", s)
sortmap["sortBy"] = s
sortmap["sortKey"] = s
iterSortBy(f, sortmap)
sortmap["append"] = sortmap["sortKey"]
iterAppend(f, sortmap) // Append() enforce unique key argv.Append
iterDelete(f, sortmap)
iterReplace(f, sortmap)
iterFind(f, sortmap)
}
for _, s := range argv.Sort { for _, s := range argv.Sort {
sortparts := strings.Split(s, ",") sortparts := strings.Split(s, ",")
sortmap["sortBy"] = sortparts[0] sortmap["sortBy"] = sortparts[0]
@ -133,7 +150,7 @@ func iterSortAll(w io.Writer, names map[string]string) {
} }
func iterSortBy(w io.Writer, names map[string]string) { func iterSortBy(w io.Writer, names map[string]string) {
fmt.Fprintln(w, "func (all *"+names["Bases"]+") Sort"+names["sortBy"]+"() *"+names["Base"]+"Iterator {") fmt.Fprintln(w, "func (all *"+names["Bases"]+") SortBy"+names["sortBy"]+"() *"+names["Base"]+"Iterator {")
fmt.Fprintln(w, " packs := all.selectAll"+names["Base"]+"()") fmt.Fprintln(w, " packs := all.selectAll"+names["Base"]+"()")
fmt.Fprintln(w, "") fmt.Fprintln(w, "")
fmt.Fprintln(w, " sort.Sort("+names["Base"]+""+names["sortBy"]+"(packs))") fmt.Fprintln(w, " sort.Sort("+names["Base"]+""+names["sortBy"]+"(packs))")