212 lines
5.6 KiB
Go
212 lines
5.6 KiB
Go
package forgepb
|
|
|
|
// for golang repos, this is an attempt to build the package
|
|
//
|
|
// Additions to 'go build' that are attempted here:
|
|
//
|
|
// * detect packages that are plugins
|
|
// * run autogenpb packages that have .proto protobuf files
|
|
// * use some 'standard' ldflags (VERISON, BUILDTIME)
|
|
//
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"go.wit.com/lib/gui/shell"
|
|
"go.wit.com/lib/protobuf/gitpb"
|
|
"go.wit.com/log"
|
|
)
|
|
|
|
func (f *Forge) Build(repo *gitpb.Repo, userFlags []string) error {
|
|
return f.doBuild(repo, userFlags, "build")
|
|
}
|
|
|
|
func (f *Forge) Install(repo *gitpb.Repo, userFlags []string) error {
|
|
return f.doBuild(repo, userFlags, "install")
|
|
}
|
|
|
|
func (f *Forge) doBuild(repo *gitpb.Repo, userFlags []string, goWhat string) error {
|
|
if repo == nil {
|
|
log.Warn("forge.doBuild repo == nil")
|
|
return errors.New("forge.doBuild repo == nil")
|
|
}
|
|
if f.IsGoWork() {
|
|
// when building using a go.work file, never use GO111MODULE=off
|
|
os.Unsetenv("GO111MODULE")
|
|
} else {
|
|
// when building from ~/go/src, always use GO111MODULE=off
|
|
os.Setenv("GO111MODULE", "off")
|
|
defer os.Unsetenv("GO111MODULE")
|
|
}
|
|
|
|
if f.IsGoWork() {
|
|
// there must be a valid go.mod file if compiling with go.work
|
|
if err := repo.ValidGoSum(); err != nil {
|
|
log.Warn("forge.doBuild() failed. run go-mod-clean here?")
|
|
return err
|
|
}
|
|
}
|
|
|
|
if repo.Exists(".forge") {
|
|
log.Info("custom build instructions")
|
|
data, _ := repo.ReadFile(".forge")
|
|
log.Info(".forge =", string(data))
|
|
log.Info("todo: do the custom build instructions")
|
|
return nil
|
|
}
|
|
|
|
// if not GoPrimitive, autogen each dependent git repo
|
|
if repo.GoDepsLen() != 0 {
|
|
// build the protobuf files in all protobuf repos
|
|
all := repo.GoDeps.SortByGoPath()
|
|
for all.Scan() {
|
|
t := all.Next()
|
|
found := f.FindByGoPath(t.GetGoPath())
|
|
if found.GetRepoType() == "protobuf" {
|
|
if err := f.runAutogenpb(found); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// get the version
|
|
version := repo.GetCurrentBranchVersion()
|
|
if version == "" {
|
|
version = "forgeErr"
|
|
}
|
|
|
|
if repo.CheckDirty() {
|
|
version = version + "-dirty"
|
|
}
|
|
cmd := []string{"go"}
|
|
if repo.GetRepoType() == "plugin" {
|
|
if goWhat == "install" {
|
|
log.Info("Can not go install plugins yet. just building to ~/go/lib/")
|
|
}
|
|
cmd = append(cmd, "build")
|
|
} else {
|
|
cmd = append(cmd, goWhat)
|
|
}
|
|
|
|
_, fname := filepath.Split(repo.FullPath)
|
|
homeDir, _ := os.UserHomeDir()
|
|
soname := fname + "." + version + ".so"
|
|
linkname := fname + ".so"
|
|
sopath := filepath.Join(homeDir, "go/lib/go-gui")
|
|
// if this is a plugin, use buildmode=plugin
|
|
if repo.GetRepoType() == "plugin" {
|
|
if goWhat == "install" {
|
|
fullname := filepath.Join(sopath, soname)
|
|
cmd = append(cmd, "-buildmode=plugin", "-o", fullname)
|
|
} else {
|
|
cmd = append(cmd, "-buildmode=plugin", "-o", soname)
|
|
}
|
|
}
|
|
cmd = append(cmd, "-v")
|
|
|
|
// set standard ldflag options
|
|
now := time.Now()
|
|
datestamp := now.UTC().Format("2006/01/02_1504_UTC")
|
|
// log.Info("datestamp =", datestamp)
|
|
// add some standard golang flags
|
|
ldflags := "-X main.VERSION=" + version + " "
|
|
ldflags += "-X main.BUILDTIME=" + datestamp + " "
|
|
ldflags += "-X main.GUIVERSION=" + version + "" // todo: git this from the filesystem
|
|
cmd = append(cmd, "-ldflags", ldflags)
|
|
|
|
// add any flags from the command line
|
|
// this might not actually work
|
|
// todo: test this
|
|
for _, flag := range userFlags {
|
|
cmd = append(cmd, "-ldflags", "-X "+flag)
|
|
}
|
|
|
|
testenv := os.Getenv("GO111MODULE")
|
|
if testenv == "off" {
|
|
log.Info("GO111MODULE=off", "f.goWork =", f.IsGoWork(), "f.gosrc =", f.GetGoSrc())
|
|
} else {
|
|
log.Info("GO111MODULE=", testenv, "f.goWork =", f.IsGoWork(), "f.gosrc =", f.GetGoSrc())
|
|
}
|
|
log.Info("running:", repo.FullPath)
|
|
log.Info("running:", cmd)
|
|
result := repo.RunRealtime(cmd)
|
|
if result.Exit != 0 {
|
|
// build failed
|
|
log.DaemonMode(true)
|
|
log.Info(strings.Join(result.Stdout, "\n"))
|
|
log.Info(strings.Join(result.Stderr, "\n"))
|
|
log.Info("result.Error =", result.Error)
|
|
log.Info("result.Exit =", result.Exit)
|
|
log.DaemonMode(false)
|
|
log.Warn("go build failed", cmd)
|
|
/*
|
|
pwd, _ := os.Getwd()
|
|
log.Warn("go build pwd", pwd)
|
|
res2 := shell.RunEcho(cmd)
|
|
if res2.Exit == 0 {
|
|
log.Info("again failed", res2.Exit)
|
|
log.Info("again failed cmd", strings.Join(cmd, "a"))
|
|
log.Info("again failed", strings.Join(res2.Stdout, "\n"))
|
|
}
|
|
*/
|
|
return errors.New("go " + goWhat + " failed: " + fmt.Sprint(result.Error))
|
|
}
|
|
// make symlinks
|
|
if repo.GetRepoType() == "plugin" {
|
|
cmd := []string{"ln", "-sf", soname, linkname}
|
|
if goWhat == "install" {
|
|
shell.PathRun(sopath, cmd)
|
|
} else {
|
|
repo.Run(cmd)
|
|
}
|
|
}
|
|
log.Info(strings.Join(result.Stdout, "\n"))
|
|
return nil
|
|
}
|
|
|
|
func (f *Forge) runAutogenpb(repo *gitpb.Repo) error {
|
|
// log.Info("run autogenpb here:", repo.GetGoPath())
|
|
files, err := repo.GetProtoFiles()
|
|
if err != nil {
|
|
log.Info("gitpb.GetProtoFiles()", err)
|
|
return err
|
|
}
|
|
for _, s := range files {
|
|
_, filename := filepath.Split(s)
|
|
pbfile := strings.TrimSuffix(filename, ".proto") + ".pb.go"
|
|
cmd := []string{"autogenpb", "--proto", filename}
|
|
if repo.Exists(pbfile) {
|
|
// log.Info("skip running:", cmd)
|
|
continue
|
|
}
|
|
log.Info("running:", cmd)
|
|
r := repo.RunRealtime(cmd)
|
|
if r.Error != nil {
|
|
log.Warn("")
|
|
log.Warn("autogenpb error", r.Error)
|
|
log.Warn("")
|
|
log.Warn("You might be missing autogenpb?")
|
|
log.Warn("")
|
|
log.Warn("To install it run: go install go.wit.com/apps/autogenpb@latest")
|
|
log.Warn("")
|
|
log.Sleep(2)
|
|
return r.Error
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// sortcut to find
|
|
func (f *Forge) FindWorkingDirRepo() *gitpb.Repo {
|
|
pwd, _ := os.Getwd()
|
|
basedir := strings.TrimPrefix(pwd, f.GetGoSrc())
|
|
basedir = strings.Trim(basedir, "/")
|
|
return f.FindByGoPath(basedir)
|
|
}
|