summaryrefslogtreecommitdiff
path: root/main.go
blob: 18cff0726d245f0f716bddf7f5b0b11d28669701 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//go:build go1.20
// +build go1.20

package main

import (
	"os"
	"strings"

	"github.com/alexflint/go-arg"
	"go.wit.com/lib/gui/shell"
	"go.wit.com/lib/protobuf/forgepb"
	"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 forge *forgepb.Forge // forgepb figures out how to run protoc correctly if it's needed

func main() {
	pp := arg.MustParse(&argv)

	// you need a proto file
	if argv.Proto == "" {
		log.Info("you must provide --proto <filename>")
		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)
	}

	// you need --upbase and --lobase
	if argv.Proto == "" {
		pp.WriteHelp(os.Stdout)
		os.Exit(-1)
	}

	if !shell.Exists("go.sum") {
		shell.Run([]string{"go", "mod", "init"})
		shell.Run([]string{"go", "mod", "tidy"})
	}

	cmd := []string{"go", "list", "-f", "'{{.Name}}'"}
	result := shell.Run(cmd)

	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)
	}

	// 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)
		}
	}

	// 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")
		os.Exit(-1)
	}

	// add mutex
	if err := addMutex(sortmap); err == nil {
		log.Info("adding mutex to existing protoc-gen-go file worked")
		sortmap["mutex"] = "true"
	} else {
		log.Info("adding mutex to existing protoc-gen-go file did not work")
		sortmap["mutex"] = "false"
	}

	if argv.NoSort {
		log.Info("not making sort.pb.go file (--no-sort == true)")
	} else {
		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)
	}

}