move stats collection tool to tools/ folder
diff --git a/buildkite/buildkite-stats.go b/buildkite/buildkite-stats.go
deleted file mode 100644
index 5d417b3..0000000
--- a/buildkite/buildkite-stats.go
+++ /dev/null
@@ -1,243 +0,0 @@
-package main
-
-import (
-	"encoding/csv"
-	"flag"
-	"fmt"
-	"os"
-	"sort"
-	"strconv"
-	"time"
-
-	"github.com/buildkite/go-buildkite/buildkite"
-)
-
-type durationPercentiles struct {
-	Max   time.Duration
-	Min   time.Duration
-	Pct90 time.Duration
-	Pct70 time.Duration
-	Pct50 time.Duration
-	Pct30 time.Duration
-}
-
-type dayBuildStats struct {
-	Day          time.Time
-	NumBuilds    int
-	NumFailed    int
-	NumPassed    int
-	BuildTimes   durationPercentiles
-	JobWaitTimes map[string]durationPercentiles
-}
-
-func optionsForPage(page int) *buildkite.BuildsListOptions {
-	return &buildkite.BuildsListOptions{
-		ListOptions: buildkite.ListOptions{
-			Page:    page,
-			PerPage: 100,
-		},
-	}
-}
-
-func fetchAllBuilds(org string, pipeline string, client *buildkite.Client) ([]buildkite.Build, error) {
-	page := 0
-	var builds []buildkite.Build
-	for {
-		buildsOnPage, _, err := client.Builds.ListByPipeline(org, pipeline, optionsForPage(page))
-		if err != nil {
-			return nil, err
-		}
-		if len(buildsOnPage) == 0 {
-			break
-		}
-		builds = append(builds, buildsOnPage...)
-		page++
-	}
-	return builds, nil
-}
-
-func computeDurationPercentiles(durations []time.Duration) durationPercentiles {
-	if len(durations) == 0 {
-		return durationPercentiles{}
-	}
-
-	sort.Slice(durations, func(i, j int) bool {
-		return durations[i] < durations[j]
-	})
-
-	return durationPercentiles{
-		Max:   durations[len(durations)-1],
-		Min:   durations[0],
-		Pct90: durations[9*len(durations)/10],
-		Pct70: durations[7*len(durations)/10],
-		Pct50: durations[5*len(durations)/10],
-		Pct30: durations[3*len(durations)/10],
-	}
-}
-
-func computeDayBuildStats(builds []buildkite.Build) *dayBuildStats {
-	if len(builds) == 0 {
-		return nil
-	}
-	var stats dayBuildStats
-	createdAt := builds[0].CreatedAt
-	stats.Day = time.Date(createdAt.Year(), createdAt.Month(), createdAt.Day(), 0, 0, 0, 0,
-		createdAt.Location())
-	stats.NumBuilds = len(builds)
-
-	var buildTimes []time.Duration
-	jobWaitTimes := make(map[string][]time.Duration)
-	for _, build := range builds {
-		if build.FinishedAt != nil && build.CreatedAt != nil {
-			buildTime := time.Duration(0)
-			for _, job := range build.Jobs {
-				if job.Name == nil || job.StartedAt == nil || job.CreatedAt == nil ||
-					job.FinishedAt == nil {
-					continue
-				}
-				waitTime := job.StartedAt.Time.Sub(job.CreatedAt.Time)
-				jobBuildTime := job.FinishedAt.Time.Sub(job.StartedAt.Time)
-				if jobBuildTime > buildTime {
-					// Use the maximum job build time as the duration, instead of the build's
-					// start and finish time. This is because retries of jobs also count towards
-					// the build's time.
-					buildTime = jobBuildTime
-				}
-				jobWaitTimes[*job.Name] = append(jobWaitTimes[*job.Name], waitTime)
-			}
-			buildTimes = append(buildTimes, buildTime)
-		}
-
-		if *build.State == "passed" {
-			stats.NumPassed++
-		}
-		if *build.State == "failed" {
-			stats.NumFailed++
-		}
-	}
-
-	stats.BuildTimes = computeDurationPercentiles(buildTimes)
-
-	stats.JobWaitTimes = make(map[string]durationPercentiles, len(jobWaitTimes))
-	for jobName, durations := range jobWaitTimes {
-		stats.JobWaitTimes[jobName] = computeDurationPercentiles(durations)
-	}
-
-	return &stats
-}
-
-func buildStatsPerDay(builds []buildkite.Build) ([]*dayBuildStats, []string) {
-	if len(builds) == 0 {
-		return []*dayBuildStats{}, []string{}
-	}
-
-	sort.Slice(builds, func(i, j int) bool {
-		return builds[i].CreatedAt.Time.Before(builds[j].CreatedAt.Time)
-	})
-
-	var stats []*dayBuildStats
-	day := 0
-	var dayBuilds []buildkite.Build
-	jobNamesMap := make(map[string]bool)
-	for _, build := range builds {
-		if day != build.CreatedAt.Day() {
-			if len(dayBuilds) > 0 {
-				dayStats := computeDayBuildStats(dayBuilds)
-				for jobName := range dayStats.JobWaitTimes {
-					jobNamesMap[jobName] = true
-				}
-				stats = append(stats, dayStats)
-			}
-
-			dayBuilds = nil
-			day = build.CreatedAt.Day()
-		}
-		dayBuilds = append(dayBuilds, build)
-	}
-
-	if len(dayBuilds) > 0 {
-		dayStats := computeDayBuildStats(dayBuilds)
-		for jobName := range dayStats.JobWaitTimes {
-			jobNamesMap[jobName] = true
-		}
-		stats = append(stats, dayStats)
-
-	}
-
-	var jobNames []string
-	for jobName := range jobNamesMap {
-		jobNames = append(jobNames, jobName)
-	}
-	sort.Strings(jobNames)
-
-	return stats, jobNames
-}
-
-func durationPercentilesFieldNames(prefix string) []string {
-	fieldNames := []string{"Max", "Min", "Pct90", "Pc70", "Pct50", "Pct30"}
-	for i, value := range fieldNames {
-		fieldNames[i] = prefix + "." + value
-	}
-	return fieldNames
-}
-
-func appendDurationPercentiles(line []string, stats *durationPercentiles) []string {
-	line = append(line, strconv.Itoa(int(stats.Max.Seconds())))
-	line = append(line, strconv.Itoa(int(stats.Min.Seconds())))
-	line = append(line, strconv.Itoa(int(stats.Pct90.Seconds())))
-	line = append(line, strconv.Itoa(int(stats.Pct70.Seconds())))
-	line = append(line, strconv.Itoa(int(stats.Pct50.Seconds())))
-	line = append(line, strconv.Itoa(int(stats.Pct30.Seconds())))
-
-	return line
-}
-
-func main() {
-	apiToken := os.Getenv("BUILDKITE_API_TOKEN")
-	if apiToken == "" {
-		fmt.Println("BUILDKITE_API_TOKEN environment variable not set.")
-		os.Exit(1)
-	}
-	pipelineSlug := flag.String("pipeline_slug", "", "Slug of the Buildkite pipeline")
-	flag.Parse()
-
-	if *pipelineSlug == "" {
-		flag.Usage()
-		os.Exit(1)
-	}
-
-	config, _ := buildkite.NewTokenConfig(apiToken, false)
-	client := buildkite.NewClient(config.Client())
-
-	builds, _ := fetchAllBuilds("bazel", *pipelineSlug, client)
-	stats, jobNames := buildStatsPerDay(builds)
-
-	writer := csv.NewWriter(os.Stdout)
-	defer writer.Flush()
-
-	csvHeaders := []string{"Day", "NumBuilds", "NumFailed", "NumPassed"}
-	csvHeaders = append(csvHeaders, durationPercentilesFieldNames("BuildTimes")...)
-	for _, jobName := range jobNames {
-		csvHeaders = append(csvHeaders, durationPercentilesFieldNames("WaitTimes["+jobName+"]")...)
-	}
-	writer.Write(csvHeaders)
-
-	for _, dayStats := range stats {
-		var line []string
-		line = append(line, dayStats.Day.Format("2006-01-02"))
-		line = append(line, strconv.Itoa(dayStats.NumBuilds))
-		line = append(line, strconv.Itoa(dayStats.NumFailed))
-		line = append(line, strconv.Itoa(dayStats.NumPassed))
-
-		line = appendDurationPercentiles(line, &dayStats.BuildTimes)
-
-		for _, jobName := range jobNames {
-			if waitTimes, ok := dayStats.JobWaitTimes[jobName]; ok {
-				line = appendDurationPercentiles(line, &waitTimes)
-			} else {
-				line = appendDurationPercentiles(line, &durationPercentiles{})
-			}
-		}
-		writer.Write(line)
-	}
-}