Luigit
repositories / will

will

owned by admin

scripts/coverage-ratchet.mjs

Raw
#!/usr/bin/env node
/**
 * Coverage ratchet (spec AC23): the enforced minimum is the highest coverage
 * achieved so far; it may rise, never fall. Reads the node test runner
 * coverage summary from stdin and compares against coverage-ratchet.json.
 * Run: node --test --experimental-test-coverage ... | node scripts/coverage-ratchet.mjs
 */
import { readFile, writeFile } from 'node:fs/promises'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'

const root = join(dirname(fileURLToPath(import.meta.url)), '..')
const ratchetPath = join(root, 'coverage-ratchet.json')

let input = ''
for await (const chunk of process.stdin) input += String(chunk)

// Reporter line looks like: `ℹ all files | 89.34 | 71.54 | 83.44 |`
const summaryLine = input
  .split('\n')
  .map((l) => l.replace(/^[^\w]*[\u2139]\s*/, '').trim())
  .find((l) => /^all files\b/i.test(l))
if (!summaryLine) {
  console.error('coverage-ratchet: no "all files" summary found on stdin')
  process.exit(2)
}
const cells = summaryLine.split('|').map((c) => c.trim())
const linePct = Number.parseFloat(cells[1] ?? '')
if (Number.isNaN(linePct)) {
  console.error(`coverage-ratchet: could not parse line coverage from "${summaryLine}"`)
  process.exit(2)
}

let ratchet = {}
try {
  ratchet = JSON.parse(await readFile(ratchetPath, 'utf8'))
} catch {
  ratchet = {}
}
const floor = typeof ratchet.all === 'number' ? ratchet.all : 0
const achieved = Math.floor(linePct * 10) / 10

if (achieved >= floor) {
  if (achieved > floor) {
    ratchet.all = achieved
    ratchet.updatedAt = new Date().toISOString()
    ratchet.note = 'ratchet only rises; commit the raise with the change that caused it'
    await writeFile(ratchetPath, `${JSON.stringify(ratchet, null, 2)}\n`, 'utf8')
    console.log(`coverage-ratchet: ${achieved}% >= floor ${floor}% (ratchet raised, commit it)`)
  } else {
    console.log(`coverage-ratchet: ${achieved}% >= floor ${floor}%`)
  }
} else {
  console.error(`coverage-ratchet: coverage ${achieved}% is below the committed floor ${floor}%`)
  process.exit(1)
}