summaryrefslogtreecommitdiff
path: root/protoc.go
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2025-01-13 02:50:01 -0600
committerJeff Carr <[email protected]>2025-01-13 02:50:01 -0600
commit0a3aa9230bb4d316144a610d9010d24674c79138 (patch)
tree256beafcb8895d9ab0a76bc2b4fd637af2a53836 /protoc.go
start a help system for forgev0.0.0
Diffstat (limited to 'protoc.go')
-rw-r--r--protoc.go139
1 files changed, 139 insertions, 0 deletions
diff --git a/protoc.go b/protoc.go
new file mode 100644
index 0000000..e27bd2c
--- /dev/null
+++ b/protoc.go
@@ -0,0 +1,139 @@
+package main
+
+// auto run protoc with the correct args
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/google/uuid"
+ "go.wit.com/log"
+ "golang.org/x/text/cases"
+ "golang.org/x/text/language"
+)
+
+/*
+This verifies a .proto file conforms to the autogenpb standard
+
+That means, for "toy.proto", there MUST exist:
+
+message toy {
+}
+message toys {
+}
+
+this parses the .proto file and handles anything with `autogenpb: `
+does the fruit.proto file have "message Fruits"
+does it have a Uuid & valid version ?
+
+This returns (UUID, Version, error on failure)
+*/
+func ValidProtobuf(filename string) (string, string, error) {
+ filebase := strings.TrimSuffix(filename, ".proto")
+ base := cases.Title(language.English, cases.NoLower).String(filebase)
+ pluralBase := base + "s" // to conform to autogenpb, it must have an added 's'
+
+ file, err := os.Open(filename)
+ if err != nil {
+ return "", "", err
+ }
+ defer file.Close()
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ line := scanner.Text()
+
+ prefix := "message " + pluralBase + " {"
+ if !strings.HasPrefix(line, prefix) {
+ // log.Info("nope", prefix, "line", line)
+ // nope, not this line
+ continue
+ }
+
+ scanner.Scan()
+ line = scanner.Text()
+ fields := strings.Fields(line)
+ // log.Info("GOT LINE", line)
+ if fields[0] == "string" && fields[1] != "uuid" {
+ noUuid(filename)
+ return "", "", fmt.Errorf("proto file does not have a UUID")
+ }
+ // ok, uuid is here
+ UUID := line
+ log.Info("found UUID:", line)
+
+ scanner.Scan()
+ line = scanner.Text()
+ fields = strings.Fields(line)
+ // log.Info("GOT LINE", line)
+ if fields[0] == "string" && fields[1] != "version" {
+ noUuid(filename)
+ return "", "", fmt.Errorf("proto file does not have a version")
+ }
+ // found "version", the .proto file conforms
+ version := line
+ log.Info("found Version:", line)
+ return UUID, version, nil
+ }
+ // right now, noPluralMessage does os.Exit(-1)
+ // return "", "", noPluralMessage(filename)
+ return "", "", fmt.Errorf("proto file does not have message %s", pluralBase)
+}
+
+func noPluralMessage(filename string) {
+ filebase := strings.TrimSuffix(filename, ".proto")
+ base := cases.Title(language.English, cases.NoLower).String(filebase)
+
+ log.Info("")
+ log.Info("###########################################################################")
+ log.Info("Your proto file", filename, "does not contain the correct 'message' definitions")
+ log.Info("")
+ log.Info("For autogenpb to work on your file", filename, ", you must have both names exactly:")
+ log.Info("")
+ log.Printf("message %s {\n", base)
+ log.Info("}")
+ log.Printf("message %s {\n", base+"s")
+ log.Info("}")
+ log.Info("")
+ log.Info("###########################################################################")
+ badExit(fmt.Errorf("proto file error %s", filename))
+}
+
+// message Fruits { // `autogenpb:marshal` `autogenpb:mutex`
+// string uuid = 1; // `autogenpb:uuid:be926ad9-f07f-484c-adf2-d96eeabf3079`
+// string version = 2; // `autogenpb:version:v0.0.1`
+// repeated Fruit Fruits = 3; // THIS MUST BE "Fruit" and then "Fruit" + "s"
+// }
+
+func noUuid(filename string) {
+ filebase := strings.TrimSuffix(filename, ".proto")
+ base := cases.Title(language.English, cases.NoLower).String(filebase)
+ id := uuid.New()
+
+ log.Info("")
+ log.Info("###########################################################################")
+ log.Info("Your proto file", filename, "is incorrect for 'message' ", base+"s")
+ log.Info("")
+ log.Info("For autogenpb to work on your file", filename, ",", base+"s must be exactly:")
+ log.Info("")
+ log.Info("message", base+"s", "{ // `autogenpb:marshal` `autogenpb:mutex`")
+ log.Info(" string uuid = 1; // `autogenpb:uuid:" + id.String() + "`")
+ log.Info(" string version = 2; // `autogenpb:version:v0.0.1`")
+ log.Info(" repeated", base, base+"s", " = 3; // THIS MUST BE ", base, " and then ", base+"s")
+ log.Info("}")
+ log.Info("")
+ log.Info("If you don't have a UUID, you can use the randomly generated one here")
+ log.Info("")
+ log.Info("###########################################################################")
+ badExit(fmt.Errorf("proto file error %s", filename))
+}
+
+func userInstructions() {
+ log.Info("This is likely because you don't have protoc and protoc-gen-go installed")
+ log.Info("")
+ log.Info("On debian, you can:")
+ log.Info(" apt install protobuf-compiler # for protoc")
+ log.Info(" apt install protoc-gen-go # for protoc-gen-go")
+ log.Info("")
+}