's'
This commit is contained in:
143
electron/scripts/download-chrome-for-testing.mjs
Normal file
143
electron/scripts/download-chrome-for-testing.mjs
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* 下载 Chrome for Testing(Stable / win64)完整目录到 resources/chrome-cft/chrome-win64/,
|
||||
* 与 chrome.exe 同级的 DLL 等依赖一并保留,随安装包分发,开箱即用。
|
||||
* 设置 SKIP_CHROME=1 可跳过(CI 无网环境)。
|
||||
*/
|
||||
import fs from 'fs'
|
||||
import https from 'https'
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import AdmZip from 'adm-zip'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const root = path.resolve(__dirname, '..')
|
||||
const resDir = path.join(root, 'resources', 'chrome-cft')
|
||||
const CFT_JSON_URL =
|
||||
'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json'
|
||||
const PLATFORM_KEY = 'win64'
|
||||
const markerName = '.chrome_cft_bundle_ok'
|
||||
|
||||
if (process.env.SKIP_CHROME === '1') {
|
||||
console.log('[chrome-cft] SKIP_CHROME=1,跳过下载')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
function downloadBuffer(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
https
|
||||
.get(url, (res) => {
|
||||
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
||||
downloadBuffer(res.headers.location).then(resolve).catch(reject)
|
||||
return
|
||||
}
|
||||
if (res.statusCode !== 200) {
|
||||
reject(new Error(`HTTP ${res.statusCode} ${url}`))
|
||||
return
|
||||
}
|
||||
const chunks = []
|
||||
res.on('data', (c) => chunks.push(c))
|
||||
res.on('end', () => resolve(Buffer.concat(chunks)))
|
||||
res.on('error', reject)
|
||||
})
|
||||
.on('error', reject)
|
||||
})
|
||||
}
|
||||
|
||||
function downloadToFile(url, dest) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const file = fs.createWriteStream(dest)
|
||||
https
|
||||
.get(url, (res) => {
|
||||
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
||||
file.close()
|
||||
try {
|
||||
fs.unlinkSync(dest)
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
downloadToFile(res.headers.location, dest).then(resolve).catch(reject)
|
||||
return
|
||||
}
|
||||
if (res.statusCode !== 200) {
|
||||
file.close()
|
||||
reject(new Error(`HTTP ${res.statusCode}`))
|
||||
return
|
||||
}
|
||||
res.pipe(file)
|
||||
file.on('finish', () => {
|
||||
file.close()
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
.on('error', (e) => {
|
||||
try {
|
||||
file.close()
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
reject(e)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const chromeExe = path.join(resDir, 'chrome-win64', 'chrome.exe')
|
||||
const markerPath = path.join(resDir, markerName)
|
||||
|
||||
fs.mkdirSync(resDir, { recursive: true })
|
||||
|
||||
if (fs.existsSync(chromeExe) && fs.existsSync(markerPath)) {
|
||||
console.log('[chrome-cft] 已存在完整包,跳过:', chromeExe)
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
console.log('[chrome-cft] 获取元数据:', CFT_JSON_URL)
|
||||
const metaBuf = await downloadBuffer(CFT_JSON_URL)
|
||||
const doc = JSON.parse(metaBuf.toString('utf-8'))
|
||||
const stable = doc.channels?.Stable
|
||||
const list = stable?.downloads?.chrome ?? []
|
||||
const hit = list.find((x) => x.platform === PLATFORM_KEY)
|
||||
if (!hit?.url) {
|
||||
console.error('[chrome-cft] 元数据中无', PLATFORM_KEY)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const zipPath = path.join(resDir, '_chrome-download.zip')
|
||||
console.log('[chrome-cft] 下载(体积较大):', hit.url)
|
||||
await downloadToFile(hit.url, zipPath)
|
||||
|
||||
console.log('[chrome-cft] 解压中…')
|
||||
const zip = new AdmZip(zipPath)
|
||||
const tmp = path.join(resDir, '_extract_tmp')
|
||||
if (fs.existsSync(tmp)) fs.rmSync(tmp, { recursive: true })
|
||||
fs.mkdirSync(tmp, { recursive: true })
|
||||
zip.extractAllTo(tmp, true)
|
||||
|
||||
const inner = path.join(tmp, 'chrome-win64')
|
||||
if (!fs.existsSync(path.join(inner, 'chrome.exe'))) {
|
||||
console.error('[chrome-cft] zip 内未找到 chrome-win64/chrome.exe')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const destDir = path.join(resDir, 'chrome-win64')
|
||||
if (fs.existsSync(destDir)) fs.rmSync(destDir, { recursive: true })
|
||||
fs.cpSync(inner, destDir, { recursive: true })
|
||||
fs.rmSync(tmp, { recursive: true })
|
||||
|
||||
try {
|
||||
fs.unlinkSync(zipPath)
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(resDir, 'NOTICE-ChromeForTesting.txt'),
|
||||
[
|
||||
'本目录包含 Chrome for Testing(Stable / Windows x64)。',
|
||||
'清单来源:' + CFT_JSON_URL,
|
||||
'与 chrome.exe 同目录文件均为官方 zip 原样复制,未修改二进制。',
|
||||
'',
|
||||
].join('\n'),
|
||||
'utf-8',
|
||||
)
|
||||
fs.writeFileSync(markerPath, `${stable.version}\n${new Date().toISOString()}\n`, 'utf-8')
|
||||
console.log('[chrome-cft] 完成:', chromeExe)
|
||||
Reference in New Issue
Block a user