196 lines
4.9 KiB
Go
196 lines
4.9 KiB
Go
//go:build go1.20
|
|
// +build go1.20
|
|
|
|
package main
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/alexflint/go-arg"
|
|
"github.com/go-cmd/cmd"
|
|
"go.wit.com/lib/gui/shell"
|
|
"go.wit.com/log"
|
|
"golang.org/x/text/cases"
|
|
"golang.org/x/text/language"
|
|
)
|
|
|
|
// sent via -ldflags
|
|
var VERSION string
|
|
var BUILDTIME string
|
|
|
|
var sortmap map[string]string
|
|
var marshalKeys []string
|
|
var uniqueKeys []string
|
|
|
|
func main() {
|
|
pp := arg.MustParse(&argv)
|
|
|
|
// you need a proto file
|
|
if argv.Proto == "" {
|
|
log.Info("you must provide --proto <filename>")
|
|
pp.WriteHelp(os.Stdout)
|
|
os.Exit(-1)
|
|
}
|
|
|
|
if !shell.Exists(argv.Proto) {
|
|
log.Info("protobuf", argv.Proto, "is missing")
|
|
if !argv.DryRun {
|
|
os.Exit(-1)
|
|
}
|
|
}
|
|
|
|
if !strings.HasSuffix(argv.Proto, ".proto") {
|
|
log.Info("protobuf", argv.Proto, "must end in .proto")
|
|
os.Exit(-1)
|
|
}
|
|
|
|
if err := findGlobalAutogenpb(argv.Proto); err != nil {
|
|
log.Info("autogenpb parse error:", err)
|
|
os.Exit(-1)
|
|
}
|
|
|
|
// todo, look for go.work files
|
|
if argv.GoSrc == "" {
|
|
homeDir, _ := os.UserHomeDir()
|
|
argv.GoSrc = filepath.Join(homeDir, "go/src")
|
|
}
|
|
|
|
if argv.GoPath == "" {
|
|
pwd, _ := os.Getwd()
|
|
argv.GoPath = strings.TrimPrefix(pwd, argv.GoSrc)
|
|
argv.GoPath = strings.Trim(argv.GoPath, "/")
|
|
}
|
|
log.Info(argv.GoSrc, argv.GoPath)
|
|
|
|
if !shell.Exists("go.sum") {
|
|
shell.RunQuiet([]string{"go", "mod", "init"})
|
|
shell.RunQuiet([]string{"go", "mod", "tidy"})
|
|
shell.RunQuiet([]string{"go", "mod", "edit", "-go=1.18"}) // TODO: make this a global
|
|
}
|
|
|
|
var result cmd.Status
|
|
var cmd []string
|
|
// if forge.IsGoWork() {
|
|
if false {
|
|
cmd = []string{"go", "work", "use"}
|
|
result = shell.Run(cmd)
|
|
log.Info(strings.Join(result.Stdout, "\n"))
|
|
log.Info(strings.Join(result.Stderr, "\n"))
|
|
if !shell.Exists("go.mod") {
|
|
cmd = []string{"go", "mod", "init"}
|
|
result = shell.Run(cmd)
|
|
log.Info(strings.Join(result.Stdout, "\n"))
|
|
log.Info(strings.Join(result.Stderr, "\n"))
|
|
}
|
|
cmd = []string{"go", "list", "-f", "'{{.Name}}'"}
|
|
result = shell.Run(cmd)
|
|
log.Info(strings.Join(result.Stdout, "\n"))
|
|
log.Info(strings.Join(result.Stderr, "\n"))
|
|
} else {
|
|
// TODO: switch to using forgepb
|
|
// switch to forgepb
|
|
os.Setenv("GO111MODULE", "off") // keeps go list working if go version is back versioned for compatability
|
|
cmd = []string{"go", "list", "-f", "'{{.Name}}'"}
|
|
result = shell.RunQuiet(cmd)
|
|
os.Unsetenv("GO111MODULE")
|
|
}
|
|
|
|
packageName := strings.Join(result.Stdout, "\n")
|
|
packageName = strings.TrimSpace(packageName)
|
|
packageName = strings.Trim(packageName, "'")
|
|
// log.Info("packageName == ", packageName)
|
|
|
|
protobase := strings.TrimSuffix(argv.Proto, ".proto")
|
|
|
|
sortmap = make(map[string]string)
|
|
sortmap["package"] = packageName
|
|
sortmap["protofile"] = argv.Proto
|
|
sortmap["protobase"] = protobase
|
|
if argv.LoBase == "" {
|
|
// if not set, assumed to be protobase
|
|
sortmap["base"] = protobase
|
|
} else {
|
|
sortmap["base"] = argv.LoBase
|
|
}
|
|
sortmap["lock"] = sortmap["base"] + "sMu" // is nonglobal and plural
|
|
if argv.UpBase == "" {
|
|
sortmap["Base"] = cases.Title(language.English, cases.NoLower).String(protobase)
|
|
sortmap["Bases"] = sortmap["Base"] + "s"
|
|
} else {
|
|
sortmap["Base"] = argv.UpBase
|
|
sortmap["Bases"] = sortmap["Base"] + "s"
|
|
}
|
|
|
|
if argv.DryRun {
|
|
for k, v := range sortmap {
|
|
log.Info(k, "=", v)
|
|
}
|
|
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
|
|
sortmap["protoc"] = protobase + ".pb.go"
|
|
if !shell.Exists(sortmap["protoc"]) {
|
|
if err := protocBuild(sortmap); err != nil {
|
|
log.Info("protoc build error:", err)
|
|
os.Exit(-1)
|
|
}
|
|
|
|
// experiment to add a mutex to the structs.
|
|
// this might fix my other not so great lock implementation on sort (?)
|
|
// seems to work, but proto.Marshal() breaks with nil reference
|
|
if argv.Mutex {
|
|
if err := addMutex(sortmap); err == nil {
|
|
// log.Info("adding mutex to existing protoc-gen-go file worked")
|
|
sortmap["mutex"] = "true"
|
|
sortmap["lock"] = "all"
|
|
} else {
|
|
log.Info("adding mutex to existing protoc-gen-go file did not work", err)
|
|
sortmap["mutex"] = "false"
|
|
}
|
|
}
|
|
}
|
|
|
|
// if foo.pb.go still doesn't exist, protoc failed
|
|
// exit here
|
|
if !shell.Exists(sortmap["protoc"]) {
|
|
log.Info("protoc build error.", sortmap["protoc"], "failed to be created with protoc and proto-gen-go")
|
|
badExit(errors.New("failed to be created with protoc and proto-gen-go"))
|
|
}
|
|
|
|
if argv.NoSort {
|
|
// log.Info("not making sort.pb.go file (--no-sort == true)")
|
|
} else {
|
|
if len(uniqueKeys) != 0 {
|
|
}
|
|
makeSortfile()
|
|
}
|
|
|
|
if argv.NoMarshal {
|
|
// log.Info("not making marshal.pb.go file (--no-marshal == true)")
|
|
} else {
|
|
// make the foo.marshal.pb.go file
|
|
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)
|
|
}
|