Skip to content

Commit d51f2ff

Browse files
committed
.tools: Run 'go vet ...' on each commit
Instead of just checking the tip, run 'go vet ...' on each commit in the series. This makes sure we catch errors with earlier commits even if they were fixed by subsequent commits. The bulk of the complexity here is checking out a previous commit's tree to a temporary directory, which is handled by the new GitCheckoutTree. I'd expect Git to be able to checkout an arbitrary tree to an arbitrary directory, but strangely it doesn't seem to be able to do that without side effects involving HEAD or the index. Instead, I call 'git archive ...' and pipe the results into tar to do the unpacking. You *can* unpack an archive using native Go, but there didn't seem to be a convenient tar.Reader.Extract(directory string) method. Shelling out to tar seemed more robust than writing a few dozen lines of Go, so that's what I've done. I'd expect shelling out is less portable, but we really only need this to run on Travis' Ubuntu environment [1]. We can work out a more portable approach if/when we need to support this script on a system without a compatible 'tar' command. [1]: http://docs.travis-ci.com/user/ci-environment/#Virtualization-environments Signed-off-by: W. Trevor King <wking@tremily.us>
1 parent 650828c commit d51f2ff

File tree

2 files changed

+77
-1
lines changed

2 files changed

+77
-1
lines changed

.tools/validate.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"encoding/json"
66
"flag"
77
"fmt"
8+
"io"
9+
"io/ioutil"
810
"log"
911
"os"
1012
"os/exec"
@@ -39,6 +41,9 @@ var DefaultRules = []ValidateRule{
3941
return vr
4042
},
4143
// TODO add something for the cleanliness of the c.Subject
44+
func(c CommitEntry) (vr ValidateResult) {
45+
return ExecTree(c, "go", "vet", "./...")
46+
},
4247
}
4348

4449
var (
@@ -229,3 +234,75 @@ func GitHeadCommit() (string, error) {
229234
}
230235
return strings.TrimSpace(string(output)), nil
231236
}
237+
238+
// GitCheckoutTree extracts the tree associated with the given commit
239+
// to the given directory. Unlike 'git checkout ...', it does not
240+
// alter the HEAD.
241+
func GitCheckoutTree(commit string, directory string) error {
242+
pipeReader, pipeWriter := io.Pipe()
243+
gitCmd := exec.Command("git", "archive", commit)
244+
gitCmd.Stdout = pipeWriter
245+
gitCmd.Stderr = os.Stderr
246+
tarCmd := exec.Command("tar", "-xC", directory)
247+
tarCmd.Stdin = pipeReader
248+
tarCmd.Stderr = os.Stderr
249+
err := gitCmd.Start()
250+
if err != nil {
251+
return err
252+
}
253+
defer gitCmd.Process.Kill()
254+
err = tarCmd.Start()
255+
if err != nil {
256+
return err
257+
}
258+
defer tarCmd.Process.Kill()
259+
err = gitCmd.Wait()
260+
if err != nil {
261+
return err
262+
}
263+
err = pipeWriter.Close()
264+
if err != nil {
265+
return err
266+
}
267+
err = tarCmd.Wait()
268+
if err != nil {
269+
return err
270+
}
271+
return nil
272+
}
273+
274+
// ExecTree executes a command in a checkout of the commit's tree,
275+
// wrapping any errors in a ValidateResult object.
276+
func ExecTree(c CommitEntry, args ...string) (vr ValidateResult) {
277+
vr.CommitEntry = c
278+
err := execTree(c, args...)
279+
if err == nil {
280+
vr.Pass = true
281+
vr.Msg = strings.Join(args, " ")
282+
} else {
283+
vr.Pass = false
284+
vr.Msg = fmt.Sprintf("%s : %s", strings.Join(args, " "), err.Error())
285+
}
286+
return vr
287+
}
288+
289+
// execTree executes a command in a checkout of the commit's tree
290+
func execTree(c CommitEntry, args ...string) error {
291+
dir, err := ioutil.TempDir("", "go-validate-")
292+
if err != nil {
293+
return err
294+
}
295+
defer os.RemoveAll(dir)
296+
err = GitCheckoutTree(c["commit"], dir)
297+
if err != nil {
298+
return err
299+
}
300+
cmd := exec.Command(args[0], args[1:]...)
301+
cmd.Dir = dir
302+
cmd.Stderr = os.Stderr
303+
err = cmd.Run()
304+
if err != nil {
305+
return err
306+
}
307+
return nil
308+
}

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ before_install:
1212
install: true
1313

1414
script:
15-
- go vet -x ./...
1615
- $HOME/gopath/bin/golint ./...
1716
- go run .tools/validate.go -range ${TRAVIS_COMMIT_RANGE}
1817

0 commit comments

Comments
 (0)