fix: add node-stream-zip for zip file extraction in install-bun script (#7403)

* chore(package): add node-stream-zip for zip file extraction in install-bun script

* refactor(install-uv): replace AdmZip with node-stream-zip for improved zip file extraction

* fix(install-uv): ensure correct extraction of uv binary for Unix/Linux/macOS

* refactor(install-uv): remove redundant file handling and cleanup for Unix/Linux/macOS installation

* fix(install-uv): update tar extraction command to strip leading components for Unix/Linux/macOS

* fix(install-uv): clarify comment for zip file extraction on Windows

* fix(install-bun): correct extraction directory for bun binary

* fix(install-bun, install-uv): update default versions and improve zip extraction process

* fix(install-bun): remove redundant cleanup of source directory after bun installation
This commit is contained in:
beyondkmp 2025-06-21 19:47:15 +08:00 committed by GitHub
parent b91ac0de1d
commit 37aaaee086
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 60 additions and 71 deletions

View File

@ -62,6 +62,7 @@
"@libsql/win32-x64-msvc": "^0.4.7", "@libsql/win32-x64-msvc": "^0.4.7",
"@strongtz/win32-arm64-msvc": "^0.4.7", "@strongtz/win32-arm64-msvc": "^0.4.7",
"jsdom": "26.1.0", "jsdom": "26.1.0",
"node-stream-zip": "^1.15.0",
"notion-helper": "^1.3.22", "notion-helper": "^1.3.22",
"os-proxy-config": "^1.1.2", "os-proxy-config": "^1.1.2",
"selection-hook": "^0.9.23", "selection-hook": "^0.9.23",
@ -176,7 +177,6 @@
"mermaid": "^11.6.0", "mermaid": "^11.6.0",
"mime": "^4.0.4", "mime": "^4.0.4",
"motion": "^12.10.5", "motion": "^12.10.5",
"node-stream-zip": "^1.15.0",
"npx-scope-finder": "^1.2.0", "npx-scope-finder": "^1.2.0",
"officeparser": "^4.1.1", "officeparser": "^4.1.1",
"openai": "patch:openai@npm%3A5.1.0#~/.yarn/patches/openai-npm-5.1.0-0e7b3ccb07.patch", "openai": "patch:openai@npm%3A5.1.0#~/.yarn/patches/openai-npm-5.1.0-0e7b3ccb07.patch",

View File

@ -2,12 +2,12 @@ const fs = require('fs')
const path = require('path') const path = require('path')
const os = require('os') const os = require('os')
const { execSync } = require('child_process') const { execSync } = require('child_process')
const AdmZip = require('adm-zip') const StreamZip = require('node-stream-zip')
const { downloadWithRedirects } = require('./download') const { downloadWithRedirects } = require('./download')
// Base URL for downloading bun binaries // Base URL for downloading bun binaries
const BUN_RELEASE_BASE_URL = 'https://gitcode.com/CherryHQ/bun/releases/download' const BUN_RELEASE_BASE_URL = 'https://gitcode.com/CherryHQ/bun/releases/download'
const DEFAULT_BUN_VERSION = '1.2.9' // Default fallback version const DEFAULT_BUN_VERSION = '1.2.17' // Default fallback version
// Mapping of platform+arch to binary package name // Mapping of platform+arch to binary package name
const BUN_PACKAGES = { const BUN_PACKAGES = {
@ -66,35 +66,36 @@ async function downloadBunBinary(platform, arch, version = DEFAULT_BUN_VERSION,
// Extract the zip file using adm-zip // Extract the zip file using adm-zip
console.log(`Extracting ${packageName} to ${binDir}...`) console.log(`Extracting ${packageName} to ${binDir}...`)
const zip = new AdmZip(tempFilename) const zip = new StreamZip.async({ file: tempFilename })
zip.extractAllTo(tempdir, true)
// Move files using Node.js fs // Get all entries in the zip file
const sourceDir = path.join(tempdir, packageName.split('.')[0]) const entries = await zip.entries()
const files = fs.readdirSync(sourceDir)
for (const file of files) { // Extract files directly to binDir, flattening the directory structure
const sourcePath = path.join(sourceDir, file) for (const entry of Object.values(entries)) {
const destPath = path.join(binDir, file) if (!entry.isDirectory) {
// Get just the filename without path
const filename = path.basename(entry.name)
const outputPath = path.join(binDir, filename)
fs.copyFileSync(sourcePath, destPath) console.log(`Extracting ${entry.name} -> ${filename}`)
fs.unlinkSync(sourcePath) await zip.extract(entry.name, outputPath)
// Make executable files executable on Unix-like systems
// Set executable permissions for non-Windows platforms if (platform !== 'win32') {
if (platform !== 'win32') { try {
try { fs.chmodSync(outputPath, 0o755)
// 755 permission: rwxr-xr-x } catch (chmodError) {
fs.chmodSync(destPath, '755') console.error(`Warning: Failed to set executable permissions on ${filename}`)
} catch (error) { return false
console.warn(`Warning: Failed to set executable permissions: ${error.message}`) }
} }
console.log(`Extracted ${entry.name} -> ${outputPath}`)
} }
} }
await zip.close()
// Clean up // Clean up
fs.unlinkSync(tempFilename) fs.unlinkSync(tempFilename)
fs.rmSync(sourceDir, { recursive: true })
console.log(`Successfully installed bun ${version} for ${platformKey}`) console.log(`Successfully installed bun ${version} for ${platformKey}`)
return true return true
} catch (error) { } catch (error) {

View File

@ -2,34 +2,33 @@ const fs = require('fs')
const path = require('path') const path = require('path')
const os = require('os') const os = require('os')
const { execSync } = require('child_process') const { execSync } = require('child_process')
const tar = require('tar') const StreamZip = require('node-stream-zip')
const AdmZip = require('adm-zip')
const { downloadWithRedirects } = require('./download') const { downloadWithRedirects } = require('./download')
// Base URL for downloading uv binaries // Base URL for downloading uv binaries
const UV_RELEASE_BASE_URL = 'https://gitcode.com/CherryHQ/uv/releases/download' const UV_RELEASE_BASE_URL = 'https://gitcode.com/CherryHQ/uv/releases/download'
const DEFAULT_UV_VERSION = '0.6.14' const DEFAULT_UV_VERSION = '0.7.13'
// Mapping of platform+arch to binary package name // Mapping of platform+arch to binary package name
const UV_PACKAGES = { const UV_PACKAGES = {
'darwin-arm64': 'uv-aarch64-apple-darwin.tar.gz', 'darwin-arm64': 'uv-aarch64-apple-darwin.zip',
'darwin-x64': 'uv-x86_64-apple-darwin.tar.gz', 'darwin-x64': 'uv-x86_64-apple-darwin.zip',
'win32-arm64': 'uv-aarch64-pc-windows-msvc.zip', 'win32-arm64': 'uv-aarch64-pc-windows-msvc.zip',
'win32-ia32': 'uv-i686-pc-windows-msvc.zip', 'win32-ia32': 'uv-i686-pc-windows-msvc.zip',
'win32-x64': 'uv-x86_64-pc-windows-msvc.zip', 'win32-x64': 'uv-x86_64-pc-windows-msvc.zip',
'linux-arm64': 'uv-aarch64-unknown-linux-gnu.tar.gz', 'linux-arm64': 'uv-aarch64-unknown-linux-gnu.zip',
'linux-ia32': 'uv-i686-unknown-linux-gnu.tar.gz', 'linux-ia32': 'uv-i686-unknown-linux-gnu.zip',
'linux-ppc64': 'uv-powerpc64-unknown-linux-gnu.tar.gz', 'linux-ppc64': 'uv-powerpc64-unknown-linux-gnu.zip',
'linux-ppc64le': 'uv-powerpc64le-unknown-linux-gnu.tar.gz', 'linux-ppc64le': 'uv-powerpc64le-unknown-linux-gnu.zip',
'linux-s390x': 'uv-s390x-unknown-linux-gnu.tar.gz', 'linux-s390x': 'uv-s390x-unknown-linux-gnu.zip',
'linux-x64': 'uv-x86_64-unknown-linux-gnu.tar.gz', 'linux-x64': 'uv-x86_64-unknown-linux-gnu.zip',
'linux-armv7l': 'uv-armv7-unknown-linux-gnueabihf.tar.gz', 'linux-armv7l': 'uv-armv7-unknown-linux-gnueabihf.zip',
// MUSL variants // MUSL variants
'linux-musl-arm64': 'uv-aarch64-unknown-linux-musl.tar.gz', 'linux-musl-arm64': 'uv-aarch64-unknown-linux-musl.zip',
'linux-musl-ia32': 'uv-i686-unknown-linux-musl.tar.gz', 'linux-musl-ia32': 'uv-i686-unknown-linux-musl.zip',
'linux-musl-x64': 'uv-x86_64-unknown-linux-musl.tar.gz', 'linux-musl-x64': 'uv-x86_64-unknown-linux-musl.zip',
'linux-musl-armv6l': 'uv-arm-unknown-linux-musleabihf.tar.gz', 'linux-musl-armv6l': 'uv-arm-unknown-linux-musleabihf.zip',
'linux-musl-armv7l': 'uv-armv7-unknown-linux-musleabihf.tar.gz' 'linux-musl-armv7l': 'uv-armv7-unknown-linux-musleabihf.zip'
} }
/** /**
@ -66,46 +65,35 @@ async function downloadUvBinary(platform, arch, version = DEFAULT_UV_VERSION, is
console.log(`Extracting ${packageName} to ${binDir}...`) console.log(`Extracting ${packageName} to ${binDir}...`)
// 根据文件扩展名选择解压方法 const zip = new StreamZip.async({ file: tempFilename })
if (packageName.endsWith('.zip')) {
// 使用 adm-zip 处理 zip 文件
const zip = new AdmZip(tempFilename)
zip.extractAllTo(binDir, true)
fs.unlinkSync(tempFilename)
console.log(`Successfully installed uv ${version} for ${platform}-${arch}`)
return true
} else {
// tar.gz 文件的处理保持不变
await tar.x({
file: tempFilename,
cwd: tempdir,
z: true
})
// Move files using Node.js fs // Get all entries in the zip file
const sourceDir = path.join(tempdir, packageName.split('.')[0]) const entries = await zip.entries()
const files = fs.readdirSync(sourceDir)
for (const file of files) {
const sourcePath = path.join(sourceDir, file)
const destPath = path.join(binDir, file)
fs.copyFileSync(sourcePath, destPath)
fs.unlinkSync(sourcePath)
// Set executable permissions for non-Windows platforms // Extract files directly to binDir, flattening the directory structure
for (const entry of Object.values(entries)) {
if (!entry.isDirectory) {
// Get just the filename without path
const filename = path.basename(entry.name)
const outputPath = path.join(binDir, filename)
console.log(`Extracting ${entry.name} -> ${filename}`)
await zip.extract(entry.name, outputPath)
// Make executable files executable on Unix-like systems
if (platform !== 'win32') { if (platform !== 'win32') {
try { try {
fs.chmodSync(destPath, '755') fs.chmodSync(outputPath, 0o755)
} catch (error) { } catch (chmodError) {
console.warn(`Warning: Failed to set executable permissions: ${error.message}`) console.error(`Warning: Failed to set executable permissions on ${filename}`)
return false
} }
} }
console.log(`Extracted ${entry.name} -> ${outputPath}`)
} }
// Clean up
fs.unlinkSync(tempFilename)
fs.rmSync(sourceDir, { recursive: true })
} }
await zip.close()
fs.unlinkSync(tempFilename)
console.log(`Successfully installed uv ${version} for ${platform}-${arch}`) console.log(`Successfully installed uv ${version} for ${platform}-${arch}`)
return true return true
} catch (error) { } catch (error) {