Skip to content

Commit f32159b

Browse files
committed
fix: fetch opentui linux arm64 bundle in build
1 parent fc81301 commit f32159b

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

cli/scripts/build-binary.ts

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ import {
55
chmodSync,
66
existsSync,
77
mkdirSync,
8+
mkdtempSync,
89
readdirSync,
910
readFileSync,
11+
rmSync,
1012
writeFileSync,
1113
} from 'fs'
1214
import { dirname, join } from 'path'
1315
import { fileURLToPath } from 'url'
16+
import { tmpdir } from 'os'
1417

1518
type TargetInfo = {
1619
bunTarget: string
@@ -28,6 +31,7 @@ const OVERRIDE_ARCH = process.env.OVERRIDE_ARCH ?? undefined
2831
const __filename = fileURLToPath(import.meta.url)
2932
const __dirname = dirname(__filename)
3033
const cliRoot = join(__dirname, '..')
34+
const repoRoot = dirname(cliRoot)
3135

3236
function log(message: string) {
3337
if (VERBOSE) {
@@ -128,6 +132,7 @@ async function main() {
128132
runCommand('bun', ['run', 'build:sdk'], { cwd: cliRoot })
129133

130134
patchOpenTuiAssetPaths()
135+
await ensureOpenTuiNativeBundle(targetInfo)
131136

132137
const outputFilename =
133138
targetInfo.platform === 'win32' ? `${binaryName}.exe` : binaryName
@@ -210,3 +215,103 @@ function patchOpenTuiAssetPaths() {
210215
writeFileSync(indexPath, patched)
211216
logAlways('Patched OpenTUI core tree-sitter asset paths')
212217
}
218+
219+
async function ensureOpenTuiNativeBundle(targetInfo: TargetInfo) {
220+
const packageName = `@opentui/core-${targetInfo.platform}-${targetInfo.arch}`
221+
const packageFolder = `core-${targetInfo.platform}-${targetInfo.arch}`
222+
const installTargets = [
223+
{
224+
label: 'workspace root',
225+
packagesDir: join(repoRoot, 'node_modules', '@opentui'),
226+
packageDir: join(repoRoot, 'node_modules', '@opentui', packageFolder),
227+
},
228+
{
229+
label: 'CLI workspace',
230+
packagesDir: join(cliRoot, 'node_modules', '@opentui'),
231+
packageDir: join(cliRoot, 'node_modules', '@opentui', packageFolder),
232+
},
233+
]
234+
235+
const missingTargets = installTargets.filter(({ packageDir }) => !existsSync(packageDir))
236+
if (missingTargets.length === 0) {
237+
log(`OpenTUI native bundle already present for ${targetInfo.platform}-${targetInfo.arch}`)
238+
return
239+
}
240+
241+
const corePackagePath =
242+
installTargets
243+
.map(({ packagesDir }) => join(packagesDir, 'core', 'package.json'))
244+
.find((candidate) => existsSync(candidate)) ?? null
245+
246+
if (!corePackagePath) {
247+
log('OpenTUI core package metadata missing; skipping native bundle fetch')
248+
return
249+
}
250+
const corePackageJson = JSON.parse(readFileSync(corePackagePath, 'utf8')) as {
251+
optionalDependencies?: Record<string, string>
252+
}
253+
const version = corePackageJson.optionalDependencies?.[packageName]
254+
if (!version) {
255+
log(`No optional dependency declared for ${packageName}; skipping native bundle fetch`)
256+
return
257+
}
258+
259+
const registryBase =
260+
process.env.CODEBUFF_NPM_REGISTRY ??
261+
process.env.NPM_REGISTRY_URL ??
262+
'https://registry.npmjs.org'
263+
const metadataUrl = `${registryBase.replace(/\/$/, '')}/${encodeURIComponent(packageName)}`
264+
log(`Fetching OpenTUI native bundle metadata from ${metadataUrl}`)
265+
266+
const metadataResponse = await fetch(metadataUrl)
267+
if (!metadataResponse.ok) {
268+
throw new Error(
269+
`Failed to fetch metadata for ${packageName}: ${metadataResponse.status} ${metadataResponse.statusText}`,
270+
)
271+
}
272+
273+
const metadata = (await metadataResponse.json()) as {
274+
versions?: Record<
275+
string,
276+
{
277+
dist?: {
278+
tarball?: string
279+
}
280+
}
281+
>
282+
}
283+
const tarballUrl = metadata.versions?.[version]?.dist?.tarball
284+
if (!tarballUrl) {
285+
throw new Error(`Tarball URL missing for ${packageName}@${version}`)
286+
}
287+
288+
log(`Downloading OpenTUI native bundle from ${tarballUrl}`)
289+
const tarballResponse = await fetch(tarballUrl)
290+
if (!tarballResponse.ok) {
291+
throw new Error(
292+
`Failed to download ${packageName}@${version}: ${tarballResponse.status} ${tarballResponse.statusText}`,
293+
)
294+
}
295+
296+
const tempDir = mkdtempSync(join(tmpdir(), 'opentui-'))
297+
try {
298+
const tarballPath = join(
299+
tempDir,
300+
`${packageName.split('/').pop() ?? 'package'}-${version}.tgz`,
301+
)
302+
await Bun.write(tarballPath, await tarballResponse.arrayBuffer())
303+
304+
for (const target of missingTargets) {
305+
mkdirSync(target.packagesDir, { recursive: true })
306+
mkdirSync(target.packageDir, { recursive: true })
307+
308+
runCommand('tar', ['-xzf', tarballPath, '--strip-components=1', '-C', target.packageDir])
309+
log(
310+
`Installed OpenTUI native bundle for ${targetInfo.platform}-${targetInfo.arch} in ${target.label}`,
311+
)
312+
}
313+
logAlways(`Fetched OpenTUI native bundle for ${targetInfo.platform}-${targetInfo.arch}`)
314+
} finally {
315+
rmSync(tempDir, { recursive: true, force: true })
316+
}
317+
}

0 commit comments

Comments
 (0)