func computeDayBuildStats()

in pipestats/main.go [78:127]


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
}