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",
|
"npx-scope-finder": "^1.2.0",
|
||||||
"officeparser": "^4.1.1",
|
"officeparser": "^4.1.1",
|
||||||
"p-queue": "^8.1.0",
|
"p-queue": "^8.1.0",
|
||||||
|
"tar": "^7.4.3",
|
||||||
"tokenx": "^0.4.1",
|
"tokenx": "^0.4.1",
|
||||||
"undici": "^7.4.0",
|
"undici": "^7.4.0",
|
||||||
"webdav": "4.11.4",
|
"webdav": "4.11.4",
|
||||||
|
|||||||
@ -3,6 +3,7 @@ const path = require('path')
|
|||||||
const os = require('os')
|
const os = require('os')
|
||||||
const { execSync } = require('child_process')
|
const { execSync } = require('child_process')
|
||||||
const https = require('https')
|
const https = require('https')
|
||||||
|
const AdmZip = require('adm-zip')
|
||||||
|
|
||||||
// Base URL for downloading bun binaries
|
// Base URL for downloading bun binaries
|
||||||
const BUN_RELEASE_BASE_URL = 'https://github.com/oven-sh/bun/releases/download'
|
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
|
* Downloads and extracts the bun binary for the specified platform and architecture
|
||||||
* @param {string} platform Platform to download for (e.g., 'darwin', 'win32', 'linux')
|
* @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(`Downloading bun ${version} for ${platformKey}...`)
|
||||||
console.log(`URL: ${downloadUrl}`)
|
console.log(`URL: ${downloadUrl}`)
|
||||||
|
|
||||||
// Download the file
|
// Use the new download function
|
||||||
execSync(`curl --fail -L -o "${localFilename}" "${downloadUrl}"`, { stdio: 'inherit' })
|
await downloadWithRedirects(downloadUrl, localFilename)
|
||||||
|
|
||||||
// Extract the zip file
|
// Extract the zip file using adm-zip
|
||||||
console.log(`Extracting ${packageName} to ${archDir}...`)
|
console.log(`Extracting ${packageName} to ${archDir}...`)
|
||||||
execSync(`unzip -o "${localFilename}" -d "${tempdir}"`, { stdio: 'inherit' })
|
const zip = new AdmZip(localFilename)
|
||||||
execSync(`mv ${tempdir}/${packageName.split('.')[0]}/* ${archDir}/`, { stdio: 'inherit' })
|
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.unlinkSync(localFilename)
|
||||||
|
fs.rmdirSync(sourceDir, { recursive: true })
|
||||||
|
|
||||||
console.log(`Successfully installed bun ${version} for ${platformKey}`)
|
console.log(`Successfully installed bun ${version} for ${platformKey}`)
|
||||||
return true
|
return true
|
||||||
|
|||||||
@ -3,6 +3,7 @@ const path = require('path')
|
|||||||
const os = require('os')
|
const os = require('os')
|
||||||
const { execSync } = require('child_process')
|
const { execSync } = require('child_process')
|
||||||
const https = require('https')
|
const https = require('https')
|
||||||
|
const tar = require('tar')
|
||||||
|
|
||||||
// Base URL for downloading uv binaries
|
// Base URL for downloading uv binaries
|
||||||
const UV_RELEASE_BASE_URL = 'https://github.com/astral-sh/uv/releases/download'
|
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'
|
'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
|
* Fetches the latest version of uv from GitHub API
|
||||||
* @returns {Promise<string>} The latest version tag (without 'v' prefix)
|
* @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(`Downloading uv ${version} for ${platformKey}...`)
|
||||||
console.log(`URL: ${downloadUrl}`)
|
console.log(`URL: ${downloadUrl}`)
|
||||||
|
|
||||||
// Download the file
|
// Use the new download function
|
||||||
execSync(`curl --fail -L -o "${localFilename}" "${downloadUrl}"`, { stdio: 'inherit' })
|
await downloadWithRedirects(downloadUrl, localFilename)
|
||||||
|
|
||||||
// Extract based on file extension
|
// Extract files using tar
|
||||||
console.log(`Extracting ${packageName} to ${archDir}...`)
|
console.log(`Extracting ${packageName} to ${archDir}...`)
|
||||||
if (packageName.endsWith('.tar.gz')) {
|
await tar.x({
|
||||||
execSync(`tar -xzf "${localFilename}" -C "${tempdir}"`, { stdio: 'inherit' })
|
file: localFilename,
|
||||||
} else if (packageName.endsWith('.zip')) {
|
cwd: tempdir,
|
||||||
execSync(`unzip -o "${localFilename}" -d "${tempdir}"`, { stdio: 'inherit' })
|
// 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
|
||||||
|
|
||||||
// Clean up the downloaded file
|
|
||||||
fs.unlinkSync(localFilename)
|
fs.unlinkSync(localFilename)
|
||||||
|
fs.rmdirSync(sourceDir, { recursive: true })
|
||||||
|
|
||||||
console.log(`Successfully installed uv ${version} for ${platform}-${arch}`)
|
console.log(`Successfully installed uv ${version} for ${platform}-${arch}`)
|
||||||
return true
|
return true
|
||||||
|
|||||||
@ -3262,6 +3262,7 @@ __metadata:
|
|||||||
shiki: "npm:^1.22.2"
|
shiki: "npm:^1.22.2"
|
||||||
string-width: "npm:^7.2.0"
|
string-width: "npm:^7.2.0"
|
||||||
styled-components: "npm:^6.1.11"
|
styled-components: "npm:^6.1.11"
|
||||||
|
tar: "npm:^7.4.3"
|
||||||
tinycolor2: "npm:^1.6.0"
|
tinycolor2: "npm:^1.6.0"
|
||||||
tokenx: "npm:^0.4.1"
|
tokenx: "npm:^0.4.1"
|
||||||
typescript: "npm:^5.6.2"
|
typescript: "npm:^5.6.2"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user