chadtmiller.com/knotless
Git hosted in your atproto account, on any stock PDS, fast enough for agents.
git clone knotless://chadtmiller.com/knotlessneeds the knotless git helper. set it up
// Which tests a change needs: the source files changed since tests last
// passed through `just t-changed`, and the cargo test runs that cover them.
//
// node harness/changed.mjs list them
// node harness/changed.mjs --run run them, against the harness
// `just pds` left up if there is one,
// and mark them passed
//
// Passing is a stamp file's time, target/tested.stamp; with none, every
// file counts as changed. The map is coarse on purpose: a change to the
// core crate runs everything, as everything is built on it.
import { spawnSync } from 'node:child_process'
import { existsSync, mkdirSync, readdirSync, statSync, writeFileSync } from 'node:fs'
import { dirname, join, relative, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..')
const stamp = join(root, 'target/tested.stamp')
const since = existsSync(stamp) ? statSync(stamp).mtimeMs : 0
const skip = new Set(['target', 'node_modules', '.git', 'baseline', 'build', '.svelte-kit'])
const walk = (dir, out = []) => {
for (const entry of readdirSync(dir, { withFileTypes: true })) {
if (skip.has(entry.name)) continue
const path = join(dir, entry.name)
if (entry.isDirectory()) walk(path, out)
else if (statSync(path).mtimeMs > since) out.push(relative(root, path))
}
return out
}
const changed = ['crates', 'harness', 'web', 'Cargo.toml', 'Cargo.lock']
.map((p) => join(root, p))
.filter(existsSync)
.flatMap((p) => (statSync(p).isDirectory() ? walk(p) : statSync(p).mtimeMs > since ? [relative(root, p)] : []))
const serve = (...tests) => [['-p', 'knotless-serve', '--lib'], ...tests.map((t) => ['-p', 'knotless-serve', '--test', t])]
/// The test runs for a file, and whether the pages may look different.
const runs = (file) => {
const m = (re) => file.match(re)
let x
if (m(/^crates\/knotless\/(src|tests\/common)\//) || m(/^(Cargo\.(toml|lock)|harness\/pds\.mjs|harness\/package)/)) {
return { runs: [['--workspace']], pages: true }
}
if ((x = m(/^crates\/(knotless-\w+)\/Cargo\.toml$/))) return { runs: [['-p', x[1]]], pages: x[1] === 'knotless-serve' }
if (m(/^crates\/knotless\/Cargo\.toml$/)) return { runs: [['--workspace']], pages: true }
if ((x = m(/^crates\/knotless\/tests\/(\w+)\.rs$/))) return { runs: [['-p', 'knotless', '--test', x[1]]] }
if (m(/^crates\/knotless-mcp\//)) return { runs: [['-p', 'knotless-mcp']] }
if ((x = m(/^crates\/knotless-serve\/tests\/(\w+)\.rs$/))) return { runs: [['-p', 'knotless-serve', '--test', x[1]]] }
if (m(/^crates\/knotless-serve\/src\/web\//)) return { runs: serve('web'), pages: true }
if ((x = m(/^crates\/knotless-serve\/src\/(\w+)\.rs$/))) {
const pages = { runs: serve('web'), pages: true }
return (
{
web: pages,
highlight: pages,
diff: pages,
objects: pages,
gateway: { runs: serve('gateway') },
api: { runs: serve('serve') },
smart: { runs: serve('serve') },
firehose: { runs: serve('jetstream', 'forge') },
jetstream: { runs: serve('jetstream', 'forge') },
index: { runs: serve('forge', 'web'), pages: true },
appview: { runs: serve('forge', 'web'), pages: true },
}[x[1]] ?? { runs: [['-p', 'knotless-serve'], ['-p', 'knotless-mcp']], pages: true }
)
}
if (m(/^crates\/knotless-serve\//)) return { runs: [['-p', 'knotless-serve']], pages: true }
if (m(/^harness\/shots\//) || m(/^web\//)) return { runs: [], pages: true }
if (m(/^harness\/authorize\.mjs$/)) return { runs: [['-p', 'knotless', '--test', 'oauth']] }
return { runs: [] }
}
const planned = changed.map(runs)
let all = planned.flatMap((p) => p.runs)
// A whole package, or the workspace, covers the narrower runs within it.
if (all.some((r) => r[0] === '--workspace')) all = [['--workspace']]
const whole = new Set(all.filter((r) => r.length === 2).map((r) => r[1]))
all = all.filter((r) => r.length === 2 || !whole.has(r[1]))
const unique = [...new Map(all.map((r) => [r.join(' '), r])).values()]
const pages = planned.some((p) => p.pages)
if (changed.length === 0) {
console.log('Nothing changed since tests last passed.')
process.exit(0)
}
console.log(`Changed since tests last passed${since ? '' : ' (no record of a pass, so everything)'}:`)
for (const f of changed.slice(0, 20)) console.log(` ${f}`)
if (changed.length > 20) console.log(` … and ${changed.length - 20} more`)
console.log(unique.length ? 'Tests:' : 'No tests cover these.')
for (const r of unique) console.log(` cargo test ${r.join(' ')}`)
if (pages) console.log('The pages may look different: `just shots` retakes those whose HTML changed.')
if (process.argv.includes('--run')) {
const started = Date.now()
const env = { ...process.env, KNOTLESS_TEST_NET: join(root, 'target/test-net.json') }
for (const r of unique) {
console.log(`\n$ cargo test ${r.join(' ')}`)
const res = spawnSync('rustup', ['run', 'stable', 'cargo', 'test', ...r], { cwd: root, env, stdio: 'inherit' })
if (res.status !== 0) process.exit(res.status ?? 1)
}
// Marked as of when the run began, so a file changed during it is not
// taken for tested.
mkdirSync(dirname(stamp), { recursive: true })
writeFileSync(stamp, '')
const { utimesSync } = await import('node:fs')
utimesSync(stamp, started / 1000, started / 1000)
console.log('\nPassed; marked.')
}