Files
orca/src/shared/opencode-plugin-permissions.test.ts
T
NeilandAhmed Nagy fee8143d61 fix(opencode): atomically install status plugin entrypoints
Retain complete status plugin files during replacement, symlinks and existing permissions, including legacy Windows directory permission recovery.

Fixes #24121. Continues #24131; permission-recovery review credited to pullfrog.

Co-authored-by: Ahmed Nagy <ahmednagy25t@gmail.com>
2026-10-02 20:41:21 -07:00

52 lines
1.8 KiB
TypeScript

import { build } from 'esbuild'
import { expect, it } from 'vitest'
import { mkdtempSync, readFileSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join, resolve } from 'node:path'
import { runProcess } from './child-process/run-process'
it.skipIf(process.platform === 'win32')(
'retains existing permissions when the process umask is stricter',
async () => {
const root = mkdtempSync(join(tmpdir(), 'orca-plugin-umask-'))
const pluginPath = join(root, 'plugin.js')
const fixturePath = join(root, 'permission-check.cjs')
const modulePath = resolve(process.cwd(), 'src/shared/opencode-plugin-atomic-write.ts')
try {
await build({
stdin: {
contents: `
import { chmodSync, statSync, writeFileSync } from 'node:fs';
import { writeCanonicalOpenCodePluginAtomically } from ${JSON.stringify(modulePath)};
const target = ${JSON.stringify(pluginPath)};
writeFileSync(target, 'old');
chmodSync(target, 0o664);
process.umask(0o027);
writeCanonicalOpenCodePluginAtomically(target, 'new');
console.log(statSync(target).mode & 0o777);
`,
resolveDir: process.cwd(),
loader: 'ts'
},
bundle: true,
platform: 'node',
format: 'cjs',
target: 'node22',
outfile: fixturePath,
logLevel: 'silent'
})
const result = await runProcess({
program: process.execPath,
cwd: root,
args: [fixturePath],
timeoutMs: 10_000,
maxOutputBytes: 4_096
})
expect(result.code, result.stderr).toBe(0)
expect(result.stdout.trim()).toBe(String(0o664))
expect(readFileSync(pluginPath, 'utf8')).toBe('new')
} finally {
rmSync(root, { recursive: true, force: true })
}
}
)