feat: add tar package and refactor binary installation scripts
- Added the `tar` package to handle extraction of `.tar.gz` files in the `install-uv.js` script. - Implemented a new `downloadWithRedirects` function in both `install-bun.js` and `install-uv.js` for improved file downloading with redirect handling. - Refactored the extraction process in both scripts to utilize Node.js file system methods and the `adm-zip` package for better file management and cleanup.
This commit is contained in:
parent
857bb02e50
commit
ed59e0f47e
@ -86,6 +86,7 @@
|
||||
"npx-scope-finder": "^1.2.0",
|
||||
"officeparser": "^4.1.1",
|
||||
"p-queue": "^8.1.0",
|
||||
"tar": "^7.4.3",
|
||||
"tokenx": "^0.4.1",
|
||||
"undici": "^7.4.0",
|
||||
"webdav": "4.11.4",
|
||||
|
||||
@ -3,6 +3,7 @@ const path = require('path')
|
||||
const os = require('os')
|
||||
const { execSync } = require('child_process')
|
||||
const https = require('https')
|
||||
const AdmZip = require('adm-zip')
|
||||
|
||||
// Base URL for downloading bun binaries
|
||||
const BUN_RELEASE_BASE_URL = 'https://github.com/oven-sh/bun/releases/download'
|
||||
@ -72,6 +73,41 @@ async function getLatestBunVersion() {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads a file from a URL with redirect handling
|
||||
* @param {string} url The URL to download from
|
||||
* @param {string} destinationPath The path to save the file to
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function downloadWithRedirects(url, destinationPath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const file = fs.createWriteStream(destinationPath)
|
||||
const request = (url) => {
|
||||
https
|
||||
.get(url, (response) => {
|
||||
if (response.statusCode === 302 || response.statusCode === 301) {
|
||||
// Handle redirect
|
||||
request(response.headers.location)
|
||||
return
|
||||
}
|
||||
|
||||
if (response.statusCode !== 200) {
|
||||
reject(new Error(`Failed to download: ${response.statusCode}`))
|
||||
return
|
||||
}
|
||||
|
||||
response.pipe(file)
|
||||
file.on('finish', () => {
|
||||
file.close(resolve)
|
||||
})
|
||||
})
|
||||
.on('error', reject)
|
||||
}
|
||||
|
||||
request(url)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads and extracts the bun binary for the specified platform and architecture
|
||||
* @param {string} platform Platform to download for (e.g., 'darwin', 'win32', 'linux')
|
||||
@ -107,16 +143,36 @@ async function downloadBunBinary(platform, arch, version = DEFAULT_BUN_VERSION,
|
||||
console.log(`Downloading bun ${version} for ${platformKey}...`)
|
||||
console.log(`URL: ${downloadUrl}`)
|
||||
|
||||
// Download the file
|
||||
execSync(`curl --fail -L -o "${localFilename}" "${downloadUrl}"`, { stdio: 'inherit' })
|
||||
// Use the new download function
|
||||
await downloadWithRedirects(downloadUrl, localFilename)
|
||||
|
||||
// Extract the zip file
|
||||
// Extract the zip file using adm-zip
|
||||
console.log(`Extracting ${packageName} to ${archDir}...`)
|
||||
execSync(`unzip -o "${localFilename}" -d "${tempdir}"`, { stdio: 'inherit' })
|
||||
execSync(`mv ${tempdir}/${packageName.split('.')[0]}/* ${archDir}/`, { stdio: 'inherit' })
|
||||
const zip = new AdmZip(localFilename)
|
||||
zip.extractAllTo(tempdir, true)
|
||||
|
||||
// Clean up the downloaded file
|
||||
// Move files using Node.js fs
|
||||
const sourceDir = path.join(tempdir, packageName.split('.')[0])
|
||||
const files = fs.readdirSync(sourceDir)
|
||||
for (const file of files) {
|
||||
const sourcePath = path.join(sourceDir, file)
|
||||
const destPath = path.join(archDir, file)
|
||||
fs.renameSync(sourcePath, destPath)
|
||||
|
||||
// Set executable permissions for non-Windows platforms
|
||||
if (platform !== 'win32') {
|
||||
try {
|
||||
// 755 permission: rwxr-xr-x
|
||||
fs.chmodSync(destPath, '755')
|
||||
} catch (error) {
|
||||
console.warn(`Warning: Failed to set executable permissions: ${error.message}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up
|
||||
fs.unlinkSync(localFilename)
|
||||
fs.rmdirSync(sourceDir, { recursive: true })
|
||||
|
||||
console.log(`Successfully installed bun ${version} for ${platformKey}`)
|
||||
return true
|
||||
|
||||
@ -3,6 +3,7 @@ const path = require('path')
|
||||
const os = require('os')
|
||||
const { execSync } = require('child_process')
|
||||
const https = require('https')
|
||||
const tar = require('tar')
|
||||
|
||||
// Base URL for downloading uv binaries
|
||||
const UV_RELEASE_BASE_URL = 'https://github.com/astral-sh/uv/releases/download'
|
||||
@ -30,6 +31,41 @@ const UV_PACKAGES = {
|
||||
'linux-musl-armv7l': 'uv-armv7-unknown-linux-musleabihf.tar.gz'
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads a file from a URL with redirect handling
|
||||
* @param {string} url The URL to download from
|
||||
* @param {string} destinationPath The path to save the file to
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function downloadWithRedirects(url, destinationPath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const file = fs.createWriteStream(destinationPath)
|
||||
const request = (url) => {
|
||||
https
|
||||
.get(url, (response) => {
|
||||
if (response.statusCode === 302 || response.statusCode === 301) {
|
||||
// Handle redirect
|
||||
request(response.headers.location)
|
||||
return
|
||||
}
|
||||
|
||||
if (response.statusCode !== 200) {
|
||||
reject(new Error(`Failed to download: ${response.statusCode}`))
|
||||
return
|
||||
}
|
||||
|
||||
response.pipe(file)
|
||||
file.on('finish', () => {
|
||||
file.close(resolve)
|
||||
})
|
||||
})
|
||||
.on('error', reject)
|
||||
}
|
||||
|
||||
request(url)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the latest version of uv from GitHub API
|
||||
* @returns {Promise<string>} The latest version tag (without 'v' prefix)
|
||||
@ -105,21 +141,40 @@ async function downloadUvBinary(platform, arch, version = DEFAULT_UV_VERSION, is
|
||||
console.log(`Downloading uv ${version} for ${platformKey}...`)
|
||||
console.log(`URL: ${downloadUrl}`)
|
||||
|
||||
// Download the file
|
||||
execSync(`curl --fail -L -o "${localFilename}" "${downloadUrl}"`, { stdio: 'inherit' })
|
||||
// Use the new download function
|
||||
await downloadWithRedirects(downloadUrl, localFilename)
|
||||
|
||||
// Extract based on file extension
|
||||
// Extract files using tar
|
||||
console.log(`Extracting ${packageName} to ${archDir}...`)
|
||||
if (packageName.endsWith('.tar.gz')) {
|
||||
execSync(`tar -xzf "${localFilename}" -C "${tempdir}"`, { stdio: 'inherit' })
|
||||
} else if (packageName.endsWith('.zip')) {
|
||||
execSync(`unzip -o "${localFilename}" -d "${tempdir}"`, { stdio: 'inherit' })
|
||||
await tar.x({
|
||||
file: localFilename,
|
||||
cwd: tempdir,
|
||||
// zip 文件也可以用 tar 解压
|
||||
z: packageName.endsWith('.tar.gz') // 对于 .tar.gz 文件启用 gzip 解压
|
||||
})
|
||||
|
||||
// Move files using Node.js fs
|
||||
const sourceDir = path.join(tempdir, packageName.split('.')[0])
|
||||
const files = fs.readdirSync(sourceDir)
|
||||
for (const file of files) {
|
||||
const sourcePath = path.join(sourceDir, file)
|
||||
const destPath = path.join(archDir, file)
|
||||
fs.renameSync(sourcePath, destPath)
|
||||
|
||||
// Set executable permissions for non-Windows platforms
|
||||
if (platform !== 'win32') {
|
||||
try {
|
||||
// 755 permission: rwxr-xr-x
|
||||
fs.chmodSync(destPath, '755')
|
||||
} catch (error) {
|
||||
console.warn(`Warning: Failed to set executable permissions: ${error.message}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
execSync(`mv ${tempdir}/${packageName.split('.')[0]}/* ${archDir}/`, { stdio: 'inherit' })
|
||||
|
||||
// Clean up the downloaded file
|
||||
// Clean up
|
||||
fs.unlinkSync(localFilename)
|
||||
fs.rmdirSync(sourceDir, { recursive: true })
|
||||
|
||||
console.log(`Successfully installed uv ${version} for ${platform}-${arch}`)
|
||||
return true
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user