Skip to content

Commit 43a8d1b

Browse files
authored
fix: Enable Windows builds and fix bun+pnpm install on Windows (anomalyco#4273)
1 parent 09fa84c commit 43a8d1b

2 files changed

Lines changed: 73 additions & 22 deletions

File tree

packages/opencode/script/build.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ const allTargets: {
6666
avx2: false,
6767
},
6868
{
69-
os: "windows",
69+
os: "win32",
7070
arch: "x64",
7171
},
7272
{
73-
os: "windows",
73+
os: "win32",
7474
arch: "x64",
7575
avx2: false,
7676
},
@@ -115,7 +115,7 @@ for (const item of targets) {
115115
entrypoints: ["./src/index.ts", parserWorker, workerPath],
116116
define: {
117117
OPENCODE_VERSION: `'${Script.version}'`,
118-
OTUI_TREE_SITTER_WORKER_PATH: "/$bunfs/root/" + path.relative(dir, parserWorker),
118+
OTUI_TREE_SITTER_WORKER_PATH: "/$bunfs/root/" + path.relative(dir, parserWorker).replaceAll("\\", "/"),
119119
OPENCODE_WORKER_PATH: workerPath,
120120
OPENCODE_CHANNEL: `'${Script.channel}'`,
121121
},
@@ -127,7 +127,7 @@ for (const item of targets) {
127127
{
128128
name,
129129
version: Script.version,
130-
os: [item.os === "windows" ? "win32" : item.os],
130+
os: [item.os],
131131
cpu: [item.arch],
132132
},
133133
null,

packages/opencode/script/postinstall.mjs

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function detectPlatformAndArch() {
2020
platform = "linux"
2121
break
2222
case "win32":
23-
platform = "windows"
23+
platform = "win32"
2424
break
2525
default:
2626
platform = os.platform()
@@ -50,24 +50,65 @@ function detectPlatformAndArch() {
5050
function findBinary() {
5151
const { platform, arch } = detectPlatformAndArch()
5252
const packageName = `opencode-${platform}-${arch}`
53-
const binary = platform === "windows" ? "opencode.exe" : "opencode"
53+
const binaryName = platform === "win32" ? "opencode.exe" : "opencode"
5454

5555
try {
5656
// Use require.resolve to find the package
5757
const packageJsonPath = require.resolve(`${packageName}/package.json`)
5858
const packageDir = path.dirname(packageJsonPath)
59-
const binaryPath = path.join(packageDir, "bin", binary)
59+
const binaryPath = path.join(packageDir, "bin", binaryName)
6060

6161
if (!fs.existsSync(binaryPath)) {
6262
throw new Error(`Binary not found at ${binaryPath}`)
6363
}
6464

65-
return binaryPath
65+
return { binaryPath, binaryName }
6666
} catch (error) {
6767
throw new Error(`Could not find package ${packageName}: ${error.message}`)
6868
}
6969
}
7070

71+
function prepareBinDirectory(binaryName) {
72+
const binDir = path.join(__dirname, "bin")
73+
const targetPath = path.join(binDir, binaryName)
74+
75+
// Ensure bin directory exists
76+
if (!fs.existsSync(binDir)) {
77+
fs.mkdirSync(binDir, { recursive: true })
78+
}
79+
80+
// Remove existing binary/symlink if it exists
81+
if (fs.existsSync(targetPath)) {
82+
fs.unlinkSync(targetPath)
83+
}
84+
85+
return { binDir, targetPath }
86+
}
87+
88+
function copyBinary(sourcePath, binaryName) {
89+
const { targetPath } = prepareBinDirectory(binaryName)
90+
91+
fs.copyFileSync(sourcePath, targetPath)
92+
console.log(`opencode binary installed: ${targetPath}`)
93+
94+
// Verify the file exists after operation
95+
if (!fs.existsSync(targetPath)) {
96+
throw new Error(`Failed to copy binary to ${targetPath}`)
97+
}
98+
}
99+
100+
function symlinkBinary(sourcePath, binaryName) {
101+
const { targetPath } = prepareBinDirectory(binaryName)
102+
103+
fs.symlinkSync(sourcePath, targetPath)
104+
console.log(`opencode binary symlinked: ${targetPath} -> ${sourcePath}`)
105+
106+
// Verify the file exists after operation
107+
if (!fs.existsSync(targetPath)) {
108+
throw new Error(`Failed to symlink binary to ${targetPath}`)
109+
}
110+
}
111+
71112
async function regenerateWindowsCmdWrappers() {
72113
console.log("Windows + npm detected: Forcing npm to rebuild bin links")
73114

@@ -102,27 +143,37 @@ async function main() {
102143
if (os.platform() === "win32") {
103144
// NPM eg format - npm/11.4.2 node/v24.4.1 win32 x64
104145
// Bun eg format - bun/1.2.19 npm/? node/v24.3.0 win32 x64
105-
if (process.env.npm_config_user_agent.startsWith("npm")) {
146+
// pnpm eg format - pnpm/8.10.0 npm/? node/v20.10.0 win32 x64
147+
const userAgent = process.env.npm_config_user_agent || ""
148+
149+
if (userAgent.startsWith("npm")) {
106150
await regenerateWindowsCmdWrappers()
107-
} else {
108-
console.log("Windows detected but not npm, skipping postinstall")
151+
return
152+
}
153+
154+
if (userAgent.startsWith("bun")) {
155+
console.log("Windows + bun detected: Setting up binary")
156+
const { binaryPath, binaryName } = findBinary()
157+
copyBinary(binaryPath, binaryName)
158+
return
109159
}
110-
return
111-
}
112160

113-
const binaryPath = findBinary()
114-
const binScript = path.join(__dirname, "bin", "opencode")
161+
if (userAgent.startsWith("pnpm")) {
162+
console.log("Windows + pnpm detected: Setting up binary")
163+
const { binaryPath, binaryName } = findBinary()
164+
copyBinary(binaryPath, binaryName)
165+
return
166+
}
115167

116-
// Remove existing bin script if it exists
117-
if (fs.existsSync(binScript)) {
118-
fs.unlinkSync(binScript)
168+
// Unknown package manager on Windows
169+
console.log("Windows detected but unknown package manager, skipping postinstall")
170+
return
119171
}
120172

121-
// Create symlink to the actual binary
122-
fs.symlinkSync(binaryPath, binScript)
123-
console.log(`opencode binary symlinked: ${binScript} -> ${binaryPath}`)
173+
const { binaryPath, binaryName } = findBinary()
174+
symlinkBinary(binaryPath, binaryName)
124175
} catch (error) {
125-
console.error("Failed to create opencode binary symlink:", error.message)
176+
console.error("Failed to setup opencode binary:", error.message)
126177
process.exit(1)
127178
}
128179
}

0 commit comments

Comments
 (0)