Skip to content

Commit

Permalink
Download go modules before building (#20)
Browse files Browse the repository at this point in the history
Fixes #14
  • Loading branch information
Brian Gibbins authored Mar 15, 2021
1 parent c9fe696 commit 7c67d1e
Showing 1 changed file with 53 additions and 9 deletions.
62 changes: 53 additions & 9 deletions internal/builder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"os/exec"
"path/filepath"
"text/template"
"time"

"github.com/open-telemetry/opentelemetry-collector-builder/internal/scaffold"
)
Expand All @@ -33,12 +34,17 @@ var (
ErrGoNotFound = errors.New("Go binary not found")
)

// GenerateAndCompile will generate the source files based on the given configuration and will compile it into a binary
// GenerateAndCompile will generate the source files based on the given configuration, update go mod, and will compile into a binary
func GenerateAndCompile(cfg Config) error {
if err := Generate(cfg); err != nil {
return err
}

// run go get to update go.mod and go.sum files
if err := GetModules(cfg); err != nil {
return err
}

return Compile(cfg)
}

Expand Down Expand Up @@ -83,15 +89,10 @@ func Generate(cfg Config) error {

// Compile generates a binary from the sources based on the configuration
func Compile(cfg Config) error {
goBinary := cfg.Distribution.Go
// first, we test to check if we have Go at all
if _, err := exec.Command(goBinary, "env").CombinedOutput(); err != nil {
path, err := exec.LookPath("go")
if err != nil {
return ErrGoNotFound
}
goBinary = path
cfg.Logger.Info("Using go from PATH", "Go executable", path)
goBinary, err := getGoPath(cfg)
if err != nil {
return err
}

cfg.Logger.Info("Compiling")
Expand All @@ -105,6 +106,49 @@ func Compile(cfg Config) error {
return nil
}

// GetModules retrieves the go modules, updating go.mod and go.sum in the process
func GetModules(cfg Config) error {
// first, we test to check if we have Go at all
goBinary, err := getGoPath(cfg)
if err != nil {
return err
}

cfg.Logger.Info("Getting go modules")
cmd := exec.Command(goBinary, "mod", "download")
cmd.Dir = cfg.Distribution.OutputPath

// basic retry if error from go mod command (in case of transient network error). This could be improved
// retry 3 times with 5 second spacing interval
retries := 3
failReason := "unknown"
for i := 1; i <= retries; i++ {
if out, err := cmd.CombinedOutput(); err != nil {
failReason = fmt.Sprintf("%s. Output: %q", err, out)
cfg.Logger.Info("Failed modules download", "retry", fmt.Sprintf("%d/%d", i, retries))
time.Sleep(5 * time.Second)
continue
}
return nil
}
return fmt.Errorf("failed to download go modules: %s", failReason)
}

// getGoPath checks if go is present and correct, and returns a useable go bin location
func getGoPath(cfg Config) (string, error) {
goBinary := cfg.Distribution.Go
if _, err := exec.Command(goBinary, "env").CombinedOutput(); err != nil {
path, err := exec.LookPath("go")
if err != nil {
return "", ErrGoNotFound
}
goBinary = path
cfg.Logger.Info("Using go from PATH", "Go executable", path)
}

return goBinary, nil
}

func processAndWrite(cfg Config, tmpl string, outFile string, tmplParams interface{}) error {
t, err := template.New("template").Parse(tmpl)
if err != nil {
Expand Down

0 comments on commit 7c67d1e

Please sign in to comment.