mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-25 03:09:00 -06:00
/go/performance/utils: add error info
This commit is contained in:
@@ -15,15 +15,20 @@
|
||||
package dolt_builder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var Debug bool
|
||||
|
||||
const envDebug = "DEBUG"
|
||||
|
||||
const maxCapturedOutputBytes = 64 * 1024
|
||||
|
||||
func init() {
|
||||
if os.Getenv(envDebug) != "" {
|
||||
Debug = true
|
||||
@@ -38,3 +43,45 @@ func ExecCommand(ctx context.Context, name string, arg ...string) *exec.Cmd {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
// RunCommand runs cmd.
|
||||
//
|
||||
// When DEBUG is not set, stdout+stderr are captured and attached to any error so
|
||||
// failures have actionable output. When DEBUG is set, output streams directly to
|
||||
// the console.
|
||||
func RunCommand(cmd *exec.Cmd) error {
|
||||
_, err := RunCommandOutput(cmd)
|
||||
return err
|
||||
}
|
||||
|
||||
// RunCommandOutput runs cmd and returns combined stdout+stderr output when DEBUG
|
||||
// is not set. When DEBUG is set, output streams directly and returned output is
|
||||
// nil.
|
||||
func RunCommandOutput(cmd *exec.Cmd) ([]byte, error) {
|
||||
if Debug {
|
||||
return nil, cmd.Run()
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
cmd.Stdout = &buf
|
||||
cmd.Stderr = &buf
|
||||
err := cmd.Run()
|
||||
out := buf.Bytes()
|
||||
|
||||
if err != nil {
|
||||
return out, fmt.Errorf("%w\ncommand: %s\ndir: %s\noutput:\n%s", err, cmd.String(), cmd.Dir, formatOutput(out))
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func formatOutput(out []byte) string {
|
||||
if len(out) == 0 {
|
||||
return "(no output)"
|
||||
}
|
||||
if len(out) <= maxCapturedOutputBytes {
|
||||
return strings.TrimRight(string(out), "\n")
|
||||
}
|
||||
trimmed := out[len(out)-maxCapturedOutputBytes:]
|
||||
return fmt.Sprintf("... (truncated; showing last %d bytes)\n%s", maxCapturedOutputBytes, strings.TrimRight(string(trimmed), "\n"))
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
// GitVersion runs git version
|
||||
func GitVersion(ctx context.Context) error {
|
||||
checkGit := ExecCommand(ctx, "git", "version")
|
||||
err := checkGit.Run()
|
||||
err := RunCommand(checkGit)
|
||||
if err != nil {
|
||||
helpStr := "dolt-builder requires git.\n" +
|
||||
"Make sure git is installed and on your PATH.\n" +
|
||||
@@ -38,7 +38,7 @@ func GitVersion(ctx context.Context) error {
|
||||
func GitCloneBare(ctx context.Context, dir, url string) error {
|
||||
clone := ExecCommand(ctx, "git", "clone", "--bare", url)
|
||||
clone.Dir = dir
|
||||
return clone.Run()
|
||||
return RunCommand(clone)
|
||||
}
|
||||
|
||||
func CommitArg(c string) string {
|
||||
@@ -67,14 +67,14 @@ func GitCheckoutTree(ctx context.Context, repoDir string, toDir string, commit s
|
||||
read := ExecCommand(ctx, "git", "read-tree", CommitArg(commit))
|
||||
read.Dir = toDir
|
||||
read.Env = env
|
||||
if err := read.Run(); err != nil {
|
||||
if err := RunCommand(read); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
checkout := ExecCommand(ctx, "git", "checkout-index", "-a")
|
||||
checkout.Dir = toDir
|
||||
checkout.Env = env
|
||||
return checkout.Run()
|
||||
return RunCommand(checkout)
|
||||
}
|
||||
|
||||
// IsCommit returns true if a commit is not a tag
|
||||
|
||||
@@ -82,6 +82,7 @@ func Run(parentCtx context.Context, commitList []string, profilePath string) err
|
||||
}()
|
||||
|
||||
for _, commit := range commitList {
|
||||
commit := commit
|
||||
g.Go(func() error {
|
||||
return buildBinaries(ctx, tempDir, repoDir, doltBin, profilePath, commit)
|
||||
})
|
||||
@@ -135,25 +136,28 @@ func getDoltBin() (string, error) {
|
||||
func buildBinaries(ctx context.Context, tempDir, repoDir, doltBinDir, profilePath, commit string) error {
|
||||
checkoutDir := filepath.Join(tempDir, commit)
|
||||
if err := os.MkdirAll(checkoutDir, os.ModePerm); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("build %s: %w", commit, err)
|
||||
}
|
||||
|
||||
err := GitCheckoutTree(ctx, repoDir, checkoutDir, commit)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("build %s: checkout failed: %w", commit, err)
|
||||
}
|
||||
|
||||
commitDir := filepath.Join(doltBinDir, commit)
|
||||
if err := os.MkdirAll(commitDir, os.ModePerm); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("build %s: %w", commit, err)
|
||||
}
|
||||
|
||||
command, err := goBuild(ctx, checkoutDir, commitDir, profilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("build %s: go build failed: %w", commit, err)
|
||||
}
|
||||
|
||||
return doltVersion(ctx, commitDir, command)
|
||||
if err := doltVersion(ctx, commitDir, command); err != nil {
|
||||
return fmt.Errorf("build %s: dolt version failed: %w", commit, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// goBuild builds the dolt binary and returns the filename
|
||||
@@ -176,8 +180,7 @@ func goBuild(ctx context.Context, source, dest, profilePath string) (string, err
|
||||
|
||||
build := ExecCommand(ctx, "go", args...)
|
||||
build.Dir = goDir
|
||||
build.Stderr = os.Stderr
|
||||
err := build.Run()
|
||||
err := RunCommand(build)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -187,8 +190,17 @@ func goBuild(ctx context.Context, source, dest, profilePath string) (string, err
|
||||
// doltVersion prints dolt version of binary
|
||||
func doltVersion(ctx context.Context, dir, command string) error {
|
||||
doltVersion := ExecCommand(ctx, command, "version")
|
||||
doltVersion.Stderr = os.Stderr
|
||||
doltVersion.Stdout = os.Stdout
|
||||
doltVersion.Dir = dir
|
||||
return doltVersion.Run()
|
||||
if Debug {
|
||||
doltVersion.Stdout = os.Stdout
|
||||
doltVersion.Stderr = os.Stderr
|
||||
return doltVersion.Run()
|
||||
}
|
||||
|
||||
out, err := RunCommandOutput(doltVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, _ = os.Stdout.Write(out)
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user