Skip to content
File

Blob: .opencode/tools/capnp.ts

typescript74 lines
1// Shared helper for running capnpc-capnp on .capnp schema files.
2// Used by next-capnp-ordinal and compat-date-at tools.
3 
4import path from 'path';
5 
6/**
7 * Run capnpc-capnp on a .capnp file and return the canonical text output.
8 *
9 * Automatically locates the bazel-built capnp tools, building them if needed.
10 * Includes standard import paths for workerd's capnp files.
11 *
12 * @param root - Project root directory (ctx.worktree or ctx.directory)
13 * @param filePath - Absolute path to the .capnp file
14 * @returns The canonical schema text, or an error string prefixed with "Error:"
15 */
16export async function runCapnpcCapnp(
17 root: string,
18 filePath: string
19): Promise<string | { error: string }> {
20 const capnp = path.join(
21 root,
22 'bazel-bin/external/+http+capnp-cpp/src/capnp/capnp_tool'
23 );
24 const capnpcCapnp = path.join(
25 root,
26 'bazel-bin/external/+http+capnp-cpp/src/capnp/capnpc-capnp'
27 );
28 const importPath = path.join(
29 root,
30 'bazel-workerd/external/+http+capnp-cpp/src'
31 );
32 
33 // Check tools exist, build if needed
34 try {
35 await Bun.$`test -x ${capnp} && test -x ${capnpcCapnp}`.quiet();
36 } catch {
37 try {
38 await Bun.$`bazel build @capnp-cpp//src/capnp:capnp_tool @capnp-cpp//src/capnp:capnpc-capnp`
39 .cwd(root)
40 .quiet();
41 } catch {
42 return {
43 error:
44 'Could not build capnp tools. Run:\n bazel build @capnp-cpp//src/capnp:capnp_tool @capnp-cpp//src/capnp:capnpc-capnp',
45 };
46 }
47 }
48 
49 const fileDir = path.dirname(filePath);
50 const importArgs = [
51 '--no-standard-import',
52 `-I${importPath}`,
53 `-I${fileDir}`,
54 `-I${path.join(root, 'src/workerd/io')}`,
55 `-I${path.join(root, 'src/workerd/server')}`,
56 `-I${path.join(root, 'src')}`,
57 ];
58 
59 try {
60 return await Bun.$`${capnp} compile ${importArgs} -o${capnpcCapnp} ${filePath}`
61 .cwd(root)
62 .text();
63 } catch (e: any) {
64 return { error: `capnpc-capnp failed:\n${e.stderr || e.message}` };
65 }
66}
67 
68/**
69 * Resolve a .capnp file path (absolute or relative to project root).
70 */
71export function resolveCapnpPath(root: string, file: string): string {
72 return path.isAbsolute(file) ? file : path.join(root, file);
73}