Skip to content

Instantly share code, notes, and snippets.

@orta
Created December 19, 2024 22:31
Show Gist options
  • Save orta/f802e9389c77daab97e1194fad5a1bb0 to your computer and use it in GitHub Desktop.
Save orta/f802e9389c77daab97e1194fad5a1bb0 to your computer and use it in GitHub Desktop.
A script to show what changed between runs on turbo build with --summerize
// @ts-check
const { join } = require("path")
const { readFileSync, existsSync, readdirSync } = require("fs")
/** @type {Map<string, import("../../.turbo/runs/2qS2rsViUIxwnKR9LWUL64tqpCP.json")>} */
const runs = new Map()
const root = process.cwd()
if (existsSync(join(root, ".turbo/runs"))) {
for (const run of readdirSync(join(root, ".turbo/runs"))) {
runs.set(run, JSON.parse(readFileSync(join(root, ".turbo/runs", run), "utf8")))
}
}
if (!runs.size) {
console.log("No runs found")
process.exit(1)
}
const sortedRuns = [...runs.values()].sort((a, b) => a.execution.startTime - b.execution.startTime)
const latestRun = sortedRuns[sortedRuns.length - 1]
const priorRun = sortedRuns[sortedRuns.length - 2]
if (!priorRun) {
console.log("Only one run logged")
process.exit(1)
}
const date = new Date(latestRun.execution.startTime)
const ago = Date.now() - date.getTime()
const shortDateFormatter = new Intl.DateTimeFormat("en-GB", { month: "short", day: "numeric", minute: "2-digit", hour: "2-digit" })
const shortDateIntervalFormatter = new Intl.RelativeTimeFormat("en", { numeric: "auto" })
console.log(
`Latest run: ${shortDateFormatter.format(date)} (${shortDateIntervalFormatter.format(Math.round(ago / 1000 / 60), "minutes")} ago)`,
)
console.log(`Duration: ${shortDateIntervalFormatter.format(latestRun.execution.exitCode - latestRun.execution.exitCode / 1000, "seconds")}`)
console.log(
`Status: ${latestRun.execution.attempted} tasks, ${latestRun.execution.failed} failed, ${latestRun.execution.success} ran (${latestRun.execution.cached} cached)`,
)
for (const task of latestRun.tasks) {
const isCached = task.cache.local || task.cache.remote
const priorTask = priorRun.tasks.find((t) => t.taskId === task.taskId)
const priorCache = priorTask ? priorTask.cache.local || priorTask.cache.remote : false
if (isCached && !priorCache) {
console.log(`- ${task.taskId} is now cached`)
}
if (!isCached && priorCache && priorTask) {
console.log(`- ${task.taskId} is no longer cached`)
const thisInputs = new Map(Object.entries(task.inputs))
const priorInputs = new Map(Object.entries(priorTask.inputs))
const thisKeys = new Set(thisInputs.keys())
const priorKeys = new Set(priorInputs.keys())
for (const key of thisKeys) {
if (!priorKeys.has(key)) {
console.log(` - ${key} added`)
}
}
for (const key of priorKeys) {
if (!thisKeys.has(key)) {
console.log(` - ${key} removed`)
}
}
for (const [key, value] of thisInputs) {
if (value !== priorInputs.get(key)) {
console.log(` - ${key} changed`)
}
}
if (task.hash !== priorTask.hash) {
console.log(` - hash changed`)
}
if (task.hashOfExternalDependencies !== priorTask.hashOfExternalDependencies) {
console.log(` - hashOfExternalDependencies changed (external dependencies changed)`)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment