-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Expand file tree
/
Copy pathgenerate-mship-contracts.ts
More file actions
132 lines (116 loc) · 4.45 KB
/
Copy pathgenerate-mship-contracts.ts
File metadata and controls
132 lines (116 loc) · 4.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env bun
// Drive every mothership contract generator, then biome-format the
// outputs so the committed files match what biome produces on commit
// (avoids the stale-drift that comes from comparing raw json2ts output
// against biome-formatted source).
//
// `--check` regenerates into a temp directory, formats identically,
// and compares against the committed files — same semantics as the
// old per-script `--check`, but accounts for post-generate formatting.
import { spawnSync } from 'node:child_process'
import { readFileSync, unlinkSync, writeFileSync } from 'node:fs'
import { dirname, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
const GENERATORS = [
'scripts/sync-mothership-stream-contract.ts',
'scripts/sync-billing-protocol-contract.ts',
'scripts/sync-tool-catalog.ts',
'scripts/sync-trace-spans-contract.ts',
'scripts/sync-trace-attributes-contract.ts',
'scripts/sync-trace-attribute-values-contract.ts',
'scripts/sync-trace-events-contract.ts',
'scripts/sync-metrics-contract.ts',
'scripts/sync-vfs-snapshot-contract.ts',
]
// Generated files under this path. We biome-format this whole dir on
// each generate (and the temp copy on each check).
const GENERATED_DIR = 'apps/sim/lib/copilot/generated'
// `tool-schemas-v1.ts` goes through biome's `--unsafe` bracket-quote
// fixer which reformats every key of TOOL_RUNTIME_SCHEMAS. Strip it
// from the format pass so generator output stays stable on both sides.
const FORMAT_EXCLUDE = new Set(['tool-schemas-v1.ts'])
function run(cmd: string[], cwd: string, env: NodeJS.ProcessEnv = process.env): void {
const result = spawnSync(cmd[0], cmd.slice(1), {
cwd,
env,
stdio: 'inherit',
})
if (result.status !== 0) {
process.exit(result.status ?? 1)
}
}
function runGenerators(outputOverride?: string): void {
const env = { ...process.env }
for (const script of GENERATORS) {
const args = ['bun', 'run', script]
if (outputOverride) {
// Individual scripts don't accept a custom output dir; for
// --check we generate in place and snapshot before/after via
// git-index comparison (see runCheck).
}
run(args, ROOT, env)
}
}
function formatGenerated(dir: string): void {
const files = readdirNoThrow(dir).filter((f) => !FORMAT_EXCLUDE.has(f) && f.endsWith('.ts'))
if (files.length === 0) return
const paths = files.map((f) => join(dir, f))
run(['bunx', 'biome', 'check', '--write', ...paths], ROOT)
}
function readdirNoThrow(dir: string): string[] {
try {
// Bun has fs.readdirSync available as a CommonJS import
const fs = require('node:fs') as typeof import('node:fs')
return fs.readdirSync(dir)
} catch {
return []
}
}
function runCheck(): void {
const targetDir = resolve(ROOT, GENERATED_DIR)
// Snapshot current committed state
const committed: Record<string, string> = {}
for (const f of readdirNoThrow(targetDir)) {
if (!f.endsWith('.ts')) continue
committed[f] = readFileSync(join(targetDir, f), 'utf8')
}
// Regenerate in place + format, then diff against the snapshot
runGenerators()
formatGenerated(targetDir)
const stale: string[] = []
const generated = readdirNoThrow(targetDir).filter((f) => f.endsWith('.ts'))
const generatedSet = new Set(generated)
for (const [name, oldContent] of Object.entries(committed)) {
if (FORMAT_EXCLUDE.has(name)) continue
if (!generatedSet.has(name)) {
stale.push(name)
continue
}
const newContent = readFileSync(join(targetDir, name), 'utf8')
if (newContent !== oldContent) stale.push(name)
}
for (const name of generated) {
if (!(name in committed)) stale.push(name)
}
// Restore the committed state regardless of outcome (--check is readonly).
for (const [name, content] of Object.entries(committed)) {
writeFileSync(join(targetDir, name), content, 'utf8')
}
for (const name of generated) {
if (!(name in committed)) unlinkSync(join(targetDir, name))
}
if (stale.length > 0) {
console.error(`Generated contracts are stale: ${stale.join(', ')}. Run: bun run mship:generate`)
process.exit(1)
}
console.log('All generated contracts up to date.')
}
function runGenerate(): void {
runGenerators()
formatGenerated(resolve(ROOT, GENERATED_DIR))
console.log('Generated + formatted mothership contracts.')
}
const checkOnly = process.argv.includes('--check')
if (checkOnly) runCheck()
else runGenerate()