|
5 | 5 | "encoding/json" |
6 | 6 | "flag" |
7 | 7 | "fmt" |
| 8 | + "io" |
| 9 | + "io/ioutil" |
8 | 10 | "log" |
9 | 11 | "os" |
10 | 12 | "os/exec" |
@@ -39,6 +41,9 @@ var DefaultRules = []ValidateRule{ |
39 | 41 | return vr |
40 | 42 | }, |
41 | 43 | // TODO add something for the cleanliness of the c.Subject |
| 44 | + func(c CommitEntry) (vr ValidateResult) { |
| 45 | + return ExecTree(c, "go", "vet", "./...") |
| 46 | + }, |
42 | 47 | } |
43 | 48 |
|
44 | 49 | var ( |
@@ -229,3 +234,75 @@ func GitHeadCommit() (string, error) { |
229 | 234 | } |
230 | 235 | return strings.TrimSpace(string(output)), nil |
231 | 236 | } |
| 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 | +} |
0 commit comments