diff --git a/tests/scripts/build-opencode.test.js b/tests/scripts/build-opencode.test.js index 8539dd941..66359d4cc 100644 --- a/tests/scripts/build-opencode.test.js +++ b/tests/scripts/build-opencode.test.js @@ -12,12 +12,12 @@ const { getNpmPackEntry } = require("../lib/npm-pack-output") const { createManifestInstallPlan, applyInstallPlan } = require("../../scripts/lib/install-executor") const { withHookConsent } = require("../../scripts/lib/install/hook-consent") -function checkRuntime(runtimeRoot, extension, loader) { +function checkRuntime(runtimeRoot, extension, loader, installedHome = false) { const check = ` const assert = require("node:assert/strict") const path = require("node:path") const { pathToFileURL } = require("node:url") - const [root, extension] = process.argv.slice(1) + const [root, extension, installedHome] = process.argv.slice(1) const load = (name) => import(pathToFileURL(path.join(root, name + extension)).href) async function main() { @@ -36,7 +36,12 @@ function checkRuntime(runtimeRoot, extension, loader) { assert.deepEqual(Object.keys(entry), ["default"]) assert.equal(entry.default, plugins.default) const logs = [] - const plugin = await entry.default({ + // Home installs are auto-discovered. Their barrel must stay inert so + // the hooks module is initialized exactly once; published package entry + // imports continue to expose the actual plugin. + const active = installedHome === "true" ? await load("plugins/ecc-hooks") : entry + if (installedHome === "true") assert.deepEqual(await entry.default({}), {}) + const plugin = await active.default({ client: { app: { log: (event) => logs.push(event.body) } }, $: () => { throw new Error("Unexpected shell execution") }, directory: process.cwd(), @@ -52,11 +57,25 @@ function checkRuntime(runtimeRoot, extension, loader) { main().catch((error) => { console.error(error); process.exit(1) }) ` const args = loader ? ["--loader", pathToFileURL(loader).href] : [] - const result = spawnSync(process.execPath, [...args, "-e", check, runtimeRoot, extension], { - cwd: path.join(__dirname, "..", ".."), - encoding: "utf8", - }) - assert.strictEqual(result.status, 0, result.error?.message || result.stderr || result.stdout) + const fixture = fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), "ecc-opencode-runtime-")) + try { + const home = path.join(fixture, "home") + const project = path.join(fixture, "project") + fs.mkdirSync(home) + fs.mkdirSync(project) + const result = spawnSync(process.execPath, [...args, "-e", check, runtimeRoot, extension, String(installedHome)], { + cwd: project, + encoding: "utf8", + timeout: 30000, + env: { ...process.env, HOME: home, USERPROFILE: home, + CLAUDE_CONFIG_DIR: path.join(home, ".claude"), ECC_AGENT_DATA_HOME: path.join(home, ".claude"), + XDG_CONFIG_HOME: path.join(home, ".config"), XDG_DATA_HOME: path.join(home, ".local", "share"), + OPENCODE_CONFIG_DIR: installedHome ? runtimeRoot : path.join(home, ".config", "opencode") }, + }) + assert.strictEqual(result.status, 0, result.error?.message || result.stderr || result.stdout) + } finally { + fs.rmSync(fixture, { recursive: true, force: true }) + } } function runTest(name, fn) { @@ -262,6 +281,7 @@ function main() { plan.targetRoot, ".ts", path.join(repoRoot, "tests", "fixtures", "opencode-ts-loader.mjs"), + true, ) } finally { fs.rmSync(fixture, { recursive: true, force: true })