From 703ed765b20077240c7f4e113df1fcb04321de3d Mon Sep 17 00:00:00 2001 From: Chris Masone Date: Mon, 21 Dec 2015 15:45:24 -0800 Subject: [PATCH] Add ForceRunInDir() This helper allows the caller to run a command in a given directory, and panic on failure. --- tools/runner/serial.go | 8 ++++++++ tools/runner/serial_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/tools/runner/serial.go b/tools/runner/serial.go index e4337ae953..4b3281b673 100644 --- a/tools/runner/serial.go +++ b/tools/runner/serial.go @@ -32,6 +32,14 @@ func ForceRun(exe string, args ...string) { d.Chk.NoError(err) } +// ForceRunInDir runs 'exe [args...]' in the given directory, and d.Chk()s on failure. Inherits the environment of the current process. +func ForceRunInDir(dir, exe string, args ...string) { + info, err := os.Stat(dir) + d.Exp.NoError(err, "Can't stat %s", dir) + d.Exp.True(info.IsDir(), "%s must be a path to a directory.", dir) + d.Chk.NoError(runEnvDir(os.Stdout, os.Stderr, Env{}, dir, exe, args...)) +} + // runEnvDir 'exe [args...]' in dir with the environment env overlaid on that of the current process. If dir == "", use the current working directory. func runEnvDir(out, err io.Writer, env Env, dir, exe string, args ...string) error { cmd := exec.Command(exe, args...) diff --git a/tools/runner/serial_test.go b/tools/runner/serial_test.go index 420e4f1966..5f92cb8009 100644 --- a/tools/runner/serial_test.go +++ b/tools/runner/serial_test.go @@ -3,6 +3,7 @@ package runner import ( "bytes" "fmt" + "io" "io/ioutil" "os" "path/filepath" @@ -42,6 +43,34 @@ func (suite *SerialRunnerTestSuite) TearDownTest() { os.Remove(suite.dir) } +func (suite *SerialRunnerTestSuite) TestForceRunInDir() { + scriptPath := filepath.Join(suite.dir, buildFileBasename) + suite.makeTestBuildFile(scriptPath, []string{"print os.getcwd()"}) + + old := os.Stdout // keep backup of the real stdout + r, w, err := os.Pipe() + suite.NoError(err) + os.Stdout = w + defer func() { os.Stdout = old }() + defer r.Close() + + outC := make(chan string) + // copy the output in a separate goroutine so printing can't block indefinitely + go func() { + buf := &bytes.Buffer{} + io.Copy(buf, r) + outC <- buf.String() + }() + + ForceRunInDir(suite.dir, "python", scriptPath) + + w.Close() + out := strings.TrimSpace(<-outC) + actualSuiteDir, err := filepath.EvalSymlinks(suite.dir) + suite.NoError(err) + suite.Equal(actualSuiteDir, out) +} + func (suite *SerialRunnerTestSuite) TestEnvVars() { makeEnvVarPrintBuildFile := func(path, varname string) { fmtStatement := fmt.Sprintf(`print os.environ['%s']`, varname)