bun-build.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import solidPlugin from "./packages/opencode/node_modules/@opentui/solid/scripts/solid-plugin"
  2. import path from "path"
  3. import fs from "fs"
  4. const version = "@VERSION@"
  5. const pkg = path.join(process.cwd(), "packages/opencode")
  6. const parser = fs.realpathSync(path.join(pkg, "./node_modules/@opentui/core/parser.worker.js"))
  7. const worker = "./src/cli/cmd/tui/worker.ts"
  8. const target = process.env["BUN_COMPILE_TARGET"]
  9. if (!target) {
  10. throw new Error("BUN_COMPILE_TARGET not set")
  11. }
  12. process.chdir(pkg)
  13. const manifestName = "opencode-assets.manifest"
  14. const manifestPath = path.join(pkg, manifestName)
  15. const readTrackedAssets = () => {
  16. if (!fs.existsSync(manifestPath)) return []
  17. return fs
  18. .readFileSync(manifestPath, "utf8")
  19. .split("\n")
  20. .map((line) => line.trim())
  21. .filter((line) => line.length > 0)
  22. }
  23. const removeTrackedAssets = () => {
  24. for (const file of readTrackedAssets()) {
  25. const filePath = path.join(pkg, file)
  26. if (fs.existsSync(filePath)) {
  27. fs.rmSync(filePath, { force: true })
  28. }
  29. }
  30. }
  31. const assets = new Set<string>()
  32. const addAsset = async (p: string) => {
  33. const file = path.basename(p)
  34. const dest = path.join(pkg, file)
  35. await Bun.write(dest, Bun.file(p))
  36. assets.add(file)
  37. }
  38. removeTrackedAssets()
  39. const result = await Bun.build({
  40. conditions: ["browser"],
  41. tsconfig: "./tsconfig.json",
  42. plugins: [solidPlugin],
  43. sourcemap: "external",
  44. entrypoints: ["./src/index.ts", parser, worker],
  45. define: {
  46. OPENCODE_VERSION: `'@VERSION@'`,
  47. OTUI_TREE_SITTER_WORKER_PATH: "/$bunfs/root/" + path.relative(pkg, parser).replace(/\\/g, "/"),
  48. OPENCODE_CHANNEL: "'latest'",
  49. },
  50. compile: {
  51. target,
  52. outfile: "opencode",
  53. execArgv: ["--user-agent=opencode/" + version, '--env-file=""', "--"],
  54. windows: {},
  55. },
  56. })
  57. if (!result.success) {
  58. console.error("Build failed!")
  59. for (const log of result.logs) {
  60. console.error(log)
  61. }
  62. throw new Error("Compilation failed")
  63. }
  64. const assetOutputs = result.outputs?.filter((x) => x.kind === "asset") ?? []
  65. for (const x of assetOutputs) {
  66. await addAsset(x.path)
  67. }
  68. const bundle = await Bun.build({
  69. entrypoints: [worker],
  70. tsconfig: "./tsconfig.json",
  71. plugins: [solidPlugin],
  72. target: "bun",
  73. outdir: "./.opencode-worker",
  74. sourcemap: "none",
  75. })
  76. if (!bundle.success) {
  77. console.error("Worker build failed!")
  78. for (const log of bundle.logs) {
  79. console.error(log)
  80. }
  81. throw new Error("Worker compilation failed")
  82. }
  83. const workerAssets = bundle.outputs?.filter((x) => x.kind === "asset") ?? []
  84. for (const x of workerAssets) {
  85. await addAsset(x.path)
  86. }
  87. const output = bundle.outputs.find((x) => x.kind === "entry-point")
  88. if (!output) {
  89. throw new Error("Worker build produced no entry-point output")
  90. }
  91. const dest = path.join(pkg, "opencode-worker.js")
  92. await Bun.write(dest, Bun.file(output.path))
  93. fs.rmSync(path.dirname(output.path), { recursive: true, force: true })
  94. const list = Array.from(assets)
  95. await Bun.write(manifestPath, list.length > 0 ? list.join("\n") + "\n" : "")
  96. console.log("Build successful!")