package forgepb // for golang repos, this is an attempt to build the package // there might be some 'standard' ways to implement a build // that make sense. // Additions to 'go build' that are attempted here: // // * detect packages that are plugins // * autogen packages that have .proto protobuf files // * define some 'standard' ldflags // import ( "errors" "fmt" "os" "path/filepath" "strings" "time" "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") } // always assume all sources have been downloaded // todo: detect when in ~/go/src vs go.work mode 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() } 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, "-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) } 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 := repo.RunRealtime(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 }