in funcbench/main.go [233:314]
func startBenchmark(env Environment, bench *Benchmarker) ([]*benchstat.Table, error) {
wt, _ := env.Repo().Worktree()
cmpWorkTreeDir := filepath.Join(bench.scratchWorkspaceDir)
ref, err := env.Repo().Head()
if err != nil {
return nil, errors.Wrap(err, "get head")
}
// TODO move it into env? since GitHub env doesn't need this check.
if _, err := bench.c.exec("sh", "-c", "git update-index -q --ignore-submodules --refresh && git diff-files --quiet --ignore-submodules --"); err != nil {
return nil, errors.Wrap(err, "not clean worktree")
}
if env.CompareTarget() == "." {
bench.logger.Println("Assuming sub-benchmarks comparison.")
subResult, err := bench.exec(wt.Filesystem.Root(), ref.Hash())
if err != nil {
return nil, errors.Wrap(err, "execute sub-benchmark")
}
cmps, err := bench.compareSubBenchmarks(subResult)
if err != nil {
return nil, errors.Wrap(err, "comparing sub benchmarks")
}
return cmps, nil
}
// Get info about target.
targetCommit := getTargetInfo(env.Repo(), env.CompareTarget())
if targetCommit == plumbing.ZeroHash {
return nil, fmt.Errorf("cannot find target %s", env.CompareTarget())
}
bench.logger.Println("Target:", targetCommit.String(), "Current Ref:", ref.Hash().String())
if targetCommit == ref.Hash() {
return nil, fmt.Errorf("target: %s is the same as current ref %s (or is on the same commit); No changes would be expected; Aborting", targetCommit, ref.String())
}
bench.logger.Println("Assuming comparing with target (clean workdir will be checked.)")
// Execute benchmark A.
newResult, err := bench.exec(wt.Filesystem.Root(), ref.Hash())
if err != nil {
return nil, errors.Wrapf(err, "execute benchmark for A: %v", ref.Name().String())
}
// TODO move the following part before 'Execute benchmark B.' into a function Benchmarker.switchToWorkTree.
// Best effort cleanup and checkout new worktree.
if err := os.RemoveAll(cmpWorkTreeDir); err != nil {
return nil, errors.Wrapf(err, "delete worktree at %s", cmpWorkTreeDir)
}
// TODO (geekodour): switch to worktree remove once we decide not to support git<2.17
if _, err := bench.c.exec("git", "worktree", "prune"); err != nil {
return nil, errors.Wrap(err, "worktree prune")
}
bench.logger.Println("Checking out (in new workdir):", cmpWorkTreeDir, "commmit", targetCommit.String())
if _, err := bench.c.exec("git", "worktree", "add", "-f", cmpWorkTreeDir, targetCommit.String()); err != nil {
return nil, errors.Wrapf(err, "checkout %s in worktree %s", targetCommit.String(), cmpWorkTreeDir)
}
// Execute benchmark B.
oldResult, err := bench.exec(cmpWorkTreeDir, targetCommit)
if err != nil {
return nil, errors.Wrapf(err, "execute benchmark for B: %v", env.CompareTarget())
}
// Compare B vs A.
tables, err := compareBenchmarks(oldResult, newResult)
if err != nil {
return nil, errors.Wrap(err, "comparing benchmarks")
}
// Save hashes for info about benchmark.
env.SetHashStrings(targetCommit.String(), ref.Hash().String())
return tables, nil
}