workspace-adaptor.test.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import { afterAll, afterEach, describe, expect, test } from "bun:test"
  2. import path from "path"
  3. import { pathToFileURL } from "url"
  4. import { tmpdir } from "../fixture/fixture"
  5. const disableDefault = process.env.OPENCODE_DISABLE_DEFAULT_PLUGINS
  6. process.env.OPENCODE_DISABLE_DEFAULT_PLUGINS = "1"
  7. const { Plugin } = await import("../../src/plugin/index")
  8. const { Workspace } = await import("../../src/control-plane/workspace")
  9. const { Instance } = await import("../../src/project/instance")
  10. afterEach(async () => {
  11. await Instance.disposeAll()
  12. })
  13. afterAll(() => {
  14. if (disableDefault === undefined) {
  15. delete process.env.OPENCODE_DISABLE_DEFAULT_PLUGINS
  16. return
  17. }
  18. process.env.OPENCODE_DISABLE_DEFAULT_PLUGINS = disableDefault
  19. })
  20. describe("plugin.workspace", () => {
  21. test("plugin can install a workspace adaptor", async () => {
  22. await using tmp = await tmpdir({
  23. init: async (dir) => {
  24. const type = `plug-${Math.random().toString(36).slice(2)}`
  25. const file = path.join(dir, "plugin.ts")
  26. const mark = path.join(dir, "created.json")
  27. const space = path.join(dir, "space")
  28. await Bun.write(
  29. file,
  30. [
  31. "export default async ({ experimental_workspace }) => {",
  32. ` experimental_workspace.register(${JSON.stringify(type)}, {`,
  33. ' name: "plug",',
  34. ' description: "plugin workspace adaptor",',
  35. " configure(input) {",
  36. ` return { ...input, name: \"plug\", branch: \"plug/main\", directory: ${JSON.stringify(space)} }`,
  37. " },",
  38. " async create(input) {",
  39. ` await Bun.write(${JSON.stringify(mark)}, JSON.stringify(input))`,
  40. " },",
  41. " async remove() {},",
  42. " target(input) {",
  43. ' return { type: "local", directory: input.directory }',
  44. " },",
  45. " })",
  46. " return {}",
  47. "}",
  48. "",
  49. ].join("\n"),
  50. )
  51. await Bun.write(
  52. path.join(dir, "opencode.json"),
  53. JSON.stringify(
  54. {
  55. $schema: "https://opencode.ai/config.json",
  56. plugin: [pathToFileURL(file).href],
  57. },
  58. null,
  59. 2,
  60. ),
  61. )
  62. return { mark, space, type }
  63. },
  64. })
  65. const info = await Instance.provide({
  66. directory: tmp.path,
  67. fn: async () => {
  68. await Plugin.init()
  69. return Workspace.create({
  70. type: tmp.extra.type,
  71. branch: null,
  72. extra: { key: "value" },
  73. projectID: Instance.project.id,
  74. })
  75. },
  76. })
  77. expect(info.type).toBe(tmp.extra.type)
  78. expect(info.name).toBe("plug")
  79. expect(info.branch).toBe("plug/main")
  80. expect(info.directory).toBe(tmp.extra.space)
  81. expect(info.extra).toEqual({ key: "value" })
  82. expect(JSON.parse(await Bun.file(tmp.extra.mark).text())).toMatchObject({
  83. type: tmp.extra.type,
  84. name: "plug",
  85. branch: "plug/main",
  86. directory: tmp.extra.space,
  87. extra: { key: "value" },
  88. })
  89. })
  90. })