cmd/bent: initial round of testing import and cleanup

Fix Kanzi benchmark description to exclude failing benchmark.

Docker now prints helpful stuff after the container ID,
parse that more carefully.

Found a few small errors.

Corrected README download instructions.

Corrected a return code to be 0 for success.

Change-Id: Ife0199e4ec01d4f936072efe4df28d8d371c52e6
Reviewed-on: https://go-review.googlesource.com/c/benchmarks/+/320969
Trust: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
diff --git a/cmd/bent/README.md b/cmd/bent/README.md
index 067c87a..d594e75 100644
--- a/cmd/bent/README.md
+++ b/cmd/bent/README.md
@@ -14,7 +14,7 @@
 Initial usage :
 
 ```
-go get github.com/dr2chase/bent
+go install golang.org/x/benchmarks/cmd/bent@latest
 mkdir scratch
 cd scratch
 bent -I
diff --git a/cmd/bent/bent.go b/cmd/bent/bent.go
index a88c203..942b649 100644
--- a/cmd/bent/bent.go
+++ b/cmd/bent/bent.go
@@ -2,11 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.16
 // +build go1.16
 
 package main
 
 import (
+	"bufio"
 	"bytes"
 	"embed"
 	"errors"
@@ -62,7 +64,7 @@
 	"go.uber.org":   2,
 }
 
-var verbose int
+var verbose counterFlag
 
 var benchFile = "benchmarks-50.toml"         // default list of benchmarks
 var confFile = "configurations.toml"         // default list of configurations
@@ -76,10 +78,10 @@
 var noSandbox = false
 var requireSandbox = false
 var getOnly = false
-var runContainer = "" // if nonempty, skip builds and use existing named container (or binaries if -U )
-var wikiTable = false // emit the tests in a form usable in a wiki table
-var explicitAll = 0   // Include "-a" on "go test -c" test build ; repeating flag causes multiple rebuilds, useful for build benchmarking.
-var shuffle = 2       // Dimensionality of (build) shuffling; 0 = none, 1 = per-benchmark, configuration ordering, 2 = bench, config pairs, 3 = across repetitions.
+var runContainer = ""       // if nonempty, skip builds and use existing named container (or binaries if -U )
+var wikiTable = false       // emit the tests in a form usable in a wiki table
+var explicitAll counterFlag // Include "-a" on "go test -c" test build ; repeating flag causes multiple rebuilds, useful for build benchmarking.
+var shuffle = 2             // Dimensionality of (build) shuffling; 0 = none, 1 = per-benchmark, configuration ordering, 2 = bench, config pairs, 3 = across repetitions.
 
 //go:embed scripts/*
 var scripts embed.FS
@@ -138,7 +140,7 @@
 
 	flag.IntVar(&N, "N", N, "benchmark/test repeat count")
 
-	flag.Var((*counterFlag)(&explicitAll), "a", "add '-a' flag to 'go test -c' to demand full recompile. Repeat or assign a value for repeat builds for benchmarking")
+	flag.Var(&explicitAll, "a", "add '-a' flag to 'go test -c' to demand full recompile. Repeat or assign a value for repeat builds for benchmarking")
 	flag.IntVar(&shuffle, "s", shuffle, "dimensionality of (build) shuffling (0-3), 0 = none, 1 = per-benchmark, configuration ordering, 2 = bench, config pairs, 3 = across repetitions.")
 
 	flag.StringVar(&benchmarksString, "b", "", "comma-separated list of test/benchmark names (default is all)")
@@ -162,7 +164,7 @@
 
 	flag.BoolVar(&wikiTable, "W", wikiTable, "print benchmark info for a wiki table")
 
-	flag.Var((*counterFlag)(&verbose), "v", "print commands and other information (more -v = print more details)")
+	flag.Var(&verbose, "v", "print commands and other information (more -v = print more details)")
 
 	flag.Usage = func() {
 		fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
@@ -238,8 +240,8 @@
 		fmt.Println(err)
 		os.Exit(1)
 	}
-	for _, c := range todo.Configurations {
-		c.dirs = dirs
+	for i := range todo.Configurations {
+		todo.Configurations[i].dirs = dirs
 	}
 
 	var moreArgs []string
@@ -456,7 +458,7 @@
 	// and each benchmark is built buildCount (innerBuildCount) times before
 	// moving on to the next. (This tends to focus intermittent benchmarking
 	// noise on single configuration-benchmark combos.  This is the "old way".
-	buildCount := explicitAll
+	buildCount := int(explicitAll)
 	if buildCount < 0 {
 		buildCount = -buildCount
 	}
@@ -768,7 +770,14 @@
 				os.Exit(2)
 				return
 			}
-			container = strings.TrimSpace(string(output))
+			// Docker prints stuff AFTER the container, thanks, Docker.
+			sc := bufio.NewScanner(bytes.NewReader(output))
+			if !sc.Scan() {
+				fmt.Printf("Could not scan line from '%s'\n", string(output))
+				os.Exit(2)
+				return
+			}
+			container = strings.TrimSpace(sc.Text())
 			if verbose == 0 {
 				fmt.Println()
 			}
@@ -1006,7 +1015,7 @@
 			return err
 		}
 		fmt.Printf("Created Dockerfile\n")
-		os.Exit(1)
+		os.Exit(0)
 	}
 	return nil
 }
@@ -1053,8 +1062,8 @@
 		testBinDir: "testbin",
 		benchDir:   "bench",
 	}
-	for _, d := range []string{dirs.gopath, dirs.goroots} {
-		if err := os.Mkdir(d, mode); err != nil {
+	for _, d := range []string{dirs.gopath, dirs.goroots, path.Join(cwd, dirs.testBinDir), path.Join(cwd, dirs.benchDir)} {
+		if err := os.Mkdir(d, mode); err != nil && !errors.Is(err, fs.ErrExist) {
 			return nil, fmt.Errorf("error creating %v: %v", d, err)
 		}
 	}
diff --git a/cmd/bent/configs/benchmarks-50.toml b/cmd/bent/configs/benchmarks-50.toml
index 657cd4e..502d1fc 100644
--- a/cmd/bent/configs/benchmarks-50.toml
+++ b/cmd/bent/configs/benchmarks-50.toml
@@ -261,7 +261,7 @@
 [[Benchmarks]]
   Name = "kanzi"
   Repo = "github.com/flanglet/kanzi-go/benchmark"
-  Benchmarks = "Benchmark(BWTS|FPAQ|LZ|MTFT)"
+  Benchmarks = "Benchmark(BWTS|FPAQ|LZ|MTFT)$"
 
 [[Benchmarks]]
   Name = "commonmark_markdown"
diff --git a/cmd/bent/configuration.go b/cmd/bent/configuration.go
index 3abd097..a8fdf1a 100644
--- a/cmd/bent/configuration.go
+++ b/cmd/bent/configuration.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.16
 // +build go1.16
 
 package main
@@ -118,7 +119,7 @@
 			continue
 		}
 		testBinaryName := config.benchName(b)
-		c := exec.Command(cmd, path.Join(config.dirs.testBinDir, testBinaryName), b.Name)
+		c := exec.Command(cmd, path.Join(cwd, config.dirs.testBinDir, testBinaryName), b.Name)
 
 		c.Env = defaultEnv
 		if !b.NotSandboxed {
@@ -252,7 +253,7 @@
 
 	// Move generated binary to well-known place.
 	from := path.Join(cmd.Dir, bench.testBinaryName())
-	to := path.Join(config.dirs.testBinDir, config.benchName(bench))
+	to := path.Join(config.dirs.wd, config.dirs.testBinDir, config.benchName(bench))
 	err = os.Rename(from, to)
 	if err != nil {
 		fmt.Printf("There was an error renaming %s to %s, %v\n", from, to, err)