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") } // get the version version := repo.GetCurrentBranchVersion() /* loop := repo.Tags.SortByRefname() for loop.Scan() { t := loop.Next() log.Info("Build() tag:", t.Refname) } */ if repo.GoDeps == nil { repo.RedoGoMod() } if repo.GoDeps.Len() == 0 { // eh, potentially runs it twice. don't care right now log.Info("redo go.mod", repo.GetGoPath()) repo.RedoGoMod() f.Repos.ConfigSave() } // run autogenpb in all protobuf repos loop1 := repo.GoDeps.SortByGoPath() for loop1.Scan() { t := loop1.Next() found := f.Repos.FindByGoPath(t.GetGoPath()) if found.RepoType() == "protobuf" { if err := f.runAutogenpb(found); err != nil { return err } } } if repo.CheckDirty() { version = version + "-dirty" } cmd := []string{"go", goWhat} // if this is a plugin, use buildmode=plugin if repo.RepoType() == "plugin" { _, fname := filepath.Split(repo.FullPath) cmd = append(cmd, "-buildmode=plugin", "-o", fname+".so") } 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 { log.Info(strings.Join(result.Stdout, "\n")) return nil } else { log.DaemonMode(true) log.Info(strings.Join(result.Stdout, "\n")) log.Info(strings.Join(result.Stderr, "\n")) 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 build failed: " + fmt.Sprint(result.Error)) } } 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 }