make a protofile for the app itself

that turns out to be a lot of fun!
This commit is contained in:
Jeff Carr 2025-01-08 19:45:48 -06:00
parent 0a1eb821e9
commit 3fe2fde185
8 changed files with 89 additions and 72 deletions

View File

@ -1,20 +1,37 @@
VERSION = $(shell git describe --tags)
BUILDTIME = $(shell date +%Y.%m.%d)
BUILDTIME = $(shell date +%Y.%m.%d_%H%M)
run: goimports vet install
test: goimports build auto
full: clean goimports auto vet install
vet:
@GO111MODULE=off go vet
@echo this go binary package should build okay
cleanbuild:
rm -f auto.marshal.pb.go auto.sort.pb.go autogenpb
build:
GO111MODULE=off go build \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
bak:
mv -f autogenpb autogenpb.last
install:
GO111MODULE=off go install \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
auto.pb.go: auto.proto
./autogenpb --proto auto.proto --package testfiles
rm -f auto.sort.pb.go auto.marshal.pb.go
auto:
cd testfiles; rm -f go.* *.pb.go
cd testfiles; ../autogenpb --proto auto.proto --package yellow
cd testfiles; GO111MODULE=off go vet
goimports:
goimports -w *.go
@ -25,8 +42,7 @@ redomod:
go mod edit -go=1.20
reset:
# clear your terminal
reset
-rm -f auto.sort.pb.go
clean:
-rm -f go.*

View File

@ -13,8 +13,8 @@ import (
"go.wit.com/log"
)
func addMutex(names map[string]string) error {
fullname := names["protobase"] + ".pb.go"
func (pb *Files) addMutex(f *File) error {
fullname := f.Filebase + ".pb.go"
log.Info("fullname:", fullname)
data, err := os.ReadFile(fullname)
if err != nil {
@ -22,14 +22,21 @@ func addMutex(names map[string]string) error {
return err
}
w, _ := os.OpenFile(names["protobase"]+".pb.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
w, _ := os.OpenFile(f.Filebase+".pb.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
var found bool
lines := strings.Split(string(data), "\n")
for _, line := range lines {
if strings.HasPrefix(line, "package ") {
log.Info("CHANGING package:", line, "to package:", f.Package)
fmt.Fprintln(w, "package "+f.Package)
// log.Info("CHANGING package:", line, "to package:main")
// fmt.Fprintln(w, "package "+"main")
continue
}
// log.Info("line:", line)
start := "type " + names["Bases"] + " struct {"
start := "type " + "sunshine" + " struct {"
if strings.HasSuffix(line, start) {
found = true
log.Info("FOUND line:", line)

View File

@ -1,21 +0,0 @@
syntax = "proto3";
// experiment to identify .pb files incase things go sideways
package autogenpb;
message Apple { // `autogenpb:marshal`
string name = 1; // `autogenpb:unique` // generates SortByName() functions
string genus = 2; // `autogenpb:unique` // generates SortByGenus() functions
}
// autogenpb:no-sort // means don't generate sort functions
message Apples { // `autogenpb:marshal`
string uuid = 1; // could be useful for /usr/share/file/magic someday?
string version = 2; // could be used for protobuf schema change violations?
}
// `autogenpb:no-sort autogenpb:no-marshal` // means don't generate sort functions
message Pears {
string uuid = 1; // could be useful for /usr/share/file/magic someday?
string version = 2; // could be used for protobuf schema change violations?
}

View File

@ -9,6 +9,7 @@ package main
var argv args
type args struct {
Package string `arg:"--package" help:"the package name"`
LoBase string `arg:"--lobase" help:"lowercase basename"`
UpBase string `arg:"--upbase" help:"uppercase basename"`
Proto string `arg:"--proto" help:"the .proto filename"`

View File

@ -6,7 +6,8 @@ import (
)
func headerComment(w io.Writer) {
fmt.Fprintln(w, "")
// technically this should be the first line and in this exact format:
fmt.Fprintln(w, "// Code generated by go.wit.com/apps/autogenpb. DO NOT EDIT.")
fmt.Fprintln(w, "// This file was autogenerated with autogenpb", VERSION, "DO NOT EDIT")
fmt.Fprintln(w, "// go install go.wit.com/apps/autogenpb@latest")
fmt.Fprintln(w, "//")
@ -23,8 +24,9 @@ func headerComment(w io.Writer) {
}
func header(w io.Writer, names map[string]string) {
fmt.Fprintln(w, "package "+names["package"])
// header must come first
headerComment(w)
fmt.Fprintln(w, "package "+names["package"])
fmt.Fprintln(w, "import (")
fmt.Fprintln(w, " \"fmt\"")
fmt.Fprintln(w, " \"sort\"")

55
main.go
View File

@ -28,6 +28,9 @@ var uniqueKeys []string
func main() {
pp := arg.MustParse(&argv)
var pb *Files
pb = new(Files)
// you need a proto file
if argv.Proto == "" {
log.Info("you must provide --proto <filename>")
@ -47,10 +50,9 @@ func main() {
os.Exit(-1)
}
if err := findGlobalAutogenpb(argv.Proto); err != nil {
log.Info("autogenpb parse error:", err)
os.Exit(-1)
}
f := new(File)
pb.Files = append(pb.Files, f)
f.Filename = argv.Proto
// todo, look for go.work files
if argv.GoSrc == "" {
@ -65,45 +67,42 @@ func main() {
}
log.Info(argv.GoSrc, argv.GoPath)
pwd, _ := os.Getwd()
log.Info("pwd = ", pwd)
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
shell.RunQuiet([]string{"go", "mod", "edit", "-go=1.18"}) // TODO: pass this as ENV. verify protobuf version needed
}
var packageName string
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 {
if argv.Package == "" {
// 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.Join(result.Stdout, "\n")
packageName = strings.TrimSpace(packageName)
packageName = strings.Trim(packageName, "'")
// log.Info("packageName == ", packageName)
} else {
packageName = argv.Package
}
f.Package = packageName
protobase := strings.TrimSuffix(argv.Proto, ".proto")
f.Filebase = protobase
if err := pb.findGlobalAutogenpb(f); err != nil {
log.Info("autogenpb parse error:", err)
os.Exit(-1)
}
sortmap = make(map[string]string)
sortmap["package"] = packageName
@ -132,19 +131,26 @@ func main() {
}
// parse sort & marshal options from the .proto file
// this goes through the .proto files and looks
// for `autogenpb: ` lines
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
// this is helpful because the protoc-gen-go lines
// are also annoying to code by hand
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)
}
pb.addMutex(f)
os.Exit(0)
/*
// 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
@ -158,6 +164,7 @@ func main() {
sortmap["mutex"] = "false"
}
}
*/
}
// if foo.pb.go still doesn't exist, protoc failed

View File

@ -43,10 +43,10 @@ func findAutogenpb(names map[string]string) error {
return nil
}
func findGlobalAutogenpb(filename string) error {
func (pb *Files) findGlobalAutogenpb(f *File) error {
// log.Info("starting findAutogenpb() on", filename)
// read in the .proto file
data, err := os.ReadFile(filename)
data, err := os.ReadFile(f.Filename)
if err != nil {
// log.Info("open config file :", err)
return err

View File

@ -42,6 +42,11 @@ func protocBuild(names map[string]string) error {
pwd, _ := os.Getwd()
log.Info("go.Getwd()", pwd)
if !strings.HasPrefix(pwd, argv.GoSrc) {
log.Info("are you building using a go.work file? If so,")
log.Info("your paths will not match because the default")
log.Info("is to use ~/go/src so you have to specify")
log.Info("where your path is with --go-src")
log.Info("todo: use forgepb to figure this out")
return errors.New("paths don't match")
}
gopath := strings.TrimPrefix(pwd, argv.GoSrc)