mirror of
https://github.com/OpenListTeam/OpenList-Desktop.git
synced 2025-11-25 03:14:56 +08:00
182 lines
5.4 KiB
JavaScript
182 lines
5.4 KiB
JavaScript
import { execSync } from 'node:child_process'
|
|
import path from 'node:path'
|
|
|
|
import AdmZip from 'adm-zip'
|
|
import fs from 'fs-extra'
|
|
import fetch from 'node-fetch'
|
|
import { extract } from 'tar'
|
|
|
|
import { downloadFile, getFetchOptions, getOpenlistArchMap, getRcloneArchMap, platformIdentifierMap } from './utils.js'
|
|
|
|
const cwd = process.cwd()
|
|
const target = process.argv.find(arg => arg.startsWith('--target='))?.slice(9)
|
|
const platformArch = target ? platformIdentifierMap[target] : `${process.platform}-${process.arch}`
|
|
const [platform, arch] = platformArch.split('-')
|
|
const isWin = platform === 'win32'
|
|
|
|
console.log(`platform: ${platform}, arch: ${arch}`)
|
|
|
|
const sidecarHost =
|
|
target ||
|
|
execSync('rustc -vV')
|
|
.toString()
|
|
.match(/(?<=host: ).+(?=\s*)/g)[0]
|
|
|
|
if (!getOpenlistArchMap[platformArch]) {
|
|
throw new Error(`Unsupported target: ${platformArch}. Supported: ${Object.keys(getOpenlistArchMap).join(', ')}`)
|
|
}
|
|
|
|
// Rclone version management
|
|
let rcloneVersion = 'v1.70.0'
|
|
const rcloneVersionUrl = 'https://github.com/rclone/rclone/releases/latest/download/version.txt'
|
|
|
|
async function getLatestRcloneVersion() {
|
|
try {
|
|
const response = await fetch(rcloneVersionUrl, getFetchOptions())
|
|
rcloneVersion = (await response.text()).trim().replace('rclone ', '')
|
|
console.log(`Latest rclone version: ${rcloneVersion}`)
|
|
} catch (error) {
|
|
console.log('Error fetching latest rclone version:', error.message)
|
|
}
|
|
}
|
|
|
|
// openlist version management
|
|
let openlistVersion = 'v4.0.0'
|
|
|
|
async function getLatestOpenlistVersion() {
|
|
try {
|
|
const response = await fetch(
|
|
'https://api.github.com/repos/OpenListTeam/OpenList/releases/latest',
|
|
getFetchOptions()
|
|
)
|
|
const data = await response.json()
|
|
openlistVersion = data.tag_name
|
|
console.log(`Latest OpenList version: ${openlistVersion}`)
|
|
} catch (error) {
|
|
console.log('Error fetching latest OpenList version:', error.message)
|
|
}
|
|
}
|
|
|
|
const createBinaryInfo = (name, archMap, baseUrl, version = '') => {
|
|
const zipName = archMap[platformArch]
|
|
return {
|
|
name,
|
|
targetFile: `${name}-${sidecarHost}${isWin ? '.exe' : ''}`,
|
|
exeFile: `${name}${isWin ? '.exe' : ''}`,
|
|
zipFile: zipName,
|
|
downloadURL: `${baseUrl}${version ? `/${version}` : ''}/${zipName}`
|
|
}
|
|
}
|
|
|
|
// OpenList service URL
|
|
const serviceUrl = `https://github.com/Kuingsmile/openlist-desktop-service/releases/download/${sidecarHost}`
|
|
|
|
const getServiceInfo = exeName => {
|
|
const ext = isWin ? '.exe' : ''
|
|
const suffix = '-' + sidecarHost
|
|
return {
|
|
file: exeName + suffix + ext,
|
|
downloadURL: `${serviceUrl}/${exeName}${ext}`
|
|
}
|
|
}
|
|
|
|
async function resolveSidecar(binInfo) {
|
|
const { name, targetFile, zipFile, exeFile, downloadURL } = binInfo
|
|
const binaryDir = path.join(cwd, 'src-tauri', 'binary')
|
|
const binaryPath = path.join(binaryDir, targetFile)
|
|
|
|
await fs.mkdir(binaryDir, { recursive: true })
|
|
const zipPath = path.join(binaryDir, zipFile)
|
|
|
|
try {
|
|
await downloadFile(downloadURL, zipPath)
|
|
|
|
if (zipFile.endsWith('.zip')) {
|
|
const zip = new AdmZip(zipPath)
|
|
zip.extractAllTo(binaryDir, true)
|
|
|
|
if (name === 'rclone') {
|
|
const extractedDir = path.join(binaryDir, zipFile.replace('.zip', ''))
|
|
await fs.rename(path.join(extractedDir, exeFile), binaryPath)
|
|
await fs.remove(extractedDir)
|
|
} else {
|
|
await fs.rename(path.join(binaryDir, exeFile), binaryPath)
|
|
}
|
|
} else {
|
|
await extract({ cwd: binaryDir, file: zipPath })
|
|
await fs.rename(path.join(binaryDir, exeFile), binaryPath)
|
|
}
|
|
await fs.remove(zipPath)
|
|
await fs.chmod(binaryPath, 0o755)
|
|
} catch (err) {
|
|
console.error(`Error preparing "${name}":`, err.message)
|
|
await fs.rm(binaryPath, { recursive: true, force: true })
|
|
throw err
|
|
}
|
|
}
|
|
|
|
async function resolveService(resourceInfo, isChmod = true, defaultMode = 0o755) {
|
|
const { file, downloadURL } = resourceInfo
|
|
const resourceDir = path.join(cwd, 'src-tauri', 'binary')
|
|
const resourcePath = path.join(resourceDir, file)
|
|
|
|
await fs.mkdir(resourceDir, { recursive: true })
|
|
|
|
try {
|
|
await downloadFile(downloadURL, resourcePath)
|
|
if (isChmod) {
|
|
await fs.chmod(resourcePath, defaultMode)
|
|
}
|
|
console.log(`"${file}" downloaded to ${resourcePath}`)
|
|
} catch (err) {
|
|
console.error(`Error preparing "${file}":`, err.message)
|
|
await fs.rm(resourcePath, { recursive: true, force: true })
|
|
throw err
|
|
}
|
|
}
|
|
|
|
async function retryTask(name, fn, maxRetries = 5) {
|
|
for (let i = 0; i < maxRetries; i++) {
|
|
try {
|
|
console.log(`task::${name} try ${i}`)
|
|
await fn()
|
|
return
|
|
} catch (err) {
|
|
console.log(`task::${name} try ${i} ==`, err.message)
|
|
if (i === maxRetries - 1) throw err
|
|
}
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
await getLatestOpenlistVersion()
|
|
await retryTask('openlist', () =>
|
|
resolveSidecar(
|
|
createBinaryInfo(
|
|
'openlist',
|
|
getOpenlistArchMap,
|
|
'https://github.com/OpenListTeam/OpenList/releases/download',
|
|
openlistVersion
|
|
)
|
|
)
|
|
)
|
|
|
|
await retryTask('rclone', async () => {
|
|
await getLatestRcloneVersion()
|
|
await resolveSidecar(
|
|
createBinaryInfo(
|
|
'rclone',
|
|
getRcloneArchMap(rcloneVersion),
|
|
'https://github.com/rclone/rclone/releases/download',
|
|
rcloneVersion
|
|
)
|
|
)
|
|
})
|
|
|
|
await resolveService(getServiceInfo('install-openlist-service'))
|
|
await resolveService(getServiceInfo('openlist-desktop-service'))
|
|
await resolveService(getServiceInfo('uninstall-openlist-service'))
|
|
}
|
|
|
|
main().catch(console.log)
|