Files
hulaspark--hula/scripts/interactive-build-inquirer.js
2026-07-13 13:11:28 +08:00

402 lines
10 KiB
JavaScript
Vendored

#!/usr/bin/env node
import { select } from '@inquirer/prompts'
import { spawn } from 'child_process'
import os from 'os'
// 检测当前平台
function getCurrentPlatform() {
const platform = os.platform()
switch (platform) {
case 'darwin':
return { platform: 'macos', name: 'macOS' }
case 'win32':
return { platform: 'windows', name: 'Windows' }
case 'linux':
return { platform: 'linux', name: 'Linux' }
default:
return { platform: 'unknown', name: '未知平台' }
}
}
// 获取平台选择选项
function getPlatformOptions() {
const currentPlatform = getCurrentPlatform()
// 根据当前操作系统定义支持的平台
const supportedPlatforms = {
macos: ['macos', 'ios', 'android'], // macOS 可以打包 macOS、iOS、Android
windows: ['windows', 'android'], // Windows 可以打包 Windows、Android
linux: ['linux', 'android'] // Linux 可以打包 Linux、Android
}
const allPlatforms = [
{
name: `MacOS${currentPlatform.platform === 'macos' ? ' (当前平台)' : ''}`,
value: 'macos',
description: '打包 macOS 应用',
isCurrent: currentPlatform.platform === 'macos'
},
{
name: `Windows${currentPlatform.platform === 'windows' ? ' (当前平台)' : ''}`,
value: 'windows',
description: '打包 Windows 应用',
isCurrent: currentPlatform.platform === 'windows'
},
{
name: `Linux${currentPlatform.platform === 'linux' ? ' (当前平台)' : ''}`,
value: 'linux',
description: '打包 Linux 应用',
isCurrent: currentPlatform.platform === 'linux'
},
{
name: 'Android',
value: 'android',
description: '打包 Android APK',
isCurrent: false
},
{
name: 'IOS',
value: 'ios',
description: '打包 IOS 应用',
isCurrent: false
},
{
name: '取消',
value: 'cancel',
description: '退出打包',
isCurrent: false
}
]
// 获取当前系统支持的平台列表
const supported = supportedPlatforms[currentPlatform.platform] || []
// 过滤出支持的平台,保留取消选项
const platforms = allPlatforms.filter((platform) => supported.includes(platform.value) || platform.value === 'cancel')
// 将当前平台排在第一位
return platforms.sort((a, b) => {
if (a.isCurrent && !b.isCurrent) return -1
if (!a.isCurrent && b.isCurrent) return 1
return 0
})
}
// 获取包格式选项
function getBundleOptions(platform) {
switch (platform) {
case 'macos':
return [
{
name: '📦 dmg 磁盘映像',
value: 'dmg',
description: '生成 .dmg 安装包 (推荐)',
command: 'tauri build --bundles dmg'
},
{
name: '📁 app 应用包',
value: 'app',
description: '生成 .app 应用包',
command: 'tauri build --bundles app'
},
{
name: '📦 全部格式',
value: 'all',
description: '生成所有支持的格式 (.app, .dmg)',
command: 'tauri build'
},
{
name: '🔙 返回上一步',
value: 'back',
description: '返回平台选择',
command: null
}
]
case 'windows':
return [
{
name: '📦 msi 安装包',
value: 'msi',
description: '生成 .msi 安装包 (推荐)',
command: 'tauri build --bundles msi'
},
{
name: '📦 nsis 安装程序',
value: 'nsis',
description: '生成 NSIS 安装程序',
command: 'tauri build --bundles nsis'
},
{
name: '📦 全部格式',
value: 'all',
description: '生成所有支持的格式',
command: 'tauri build'
},
{
name: '🔙 返回上一步',
value: 'back',
description: '返回平台选择',
command: null
}
]
case 'linux':
return [
{
name: '📦 deb 软件包',
value: 'deb',
description: '生成 .deb 软件包 (Ubuntu/Debian)',
command: 'tauri build --bundles deb'
},
{
name: '📁 AppImage',
value: 'appimage',
description: '生成 .AppImage 便携应用',
command: 'tauri build --bundles appimage'
},
{
name: '📦 rpm 软件包',
value: 'rpm',
description: '生成 .rpm 软件包 (RedHat/CentOS)',
command: 'tauri build --bundles rpm'
},
{
name: '📦 全部格式',
value: 'all',
description: '生成所有支持的格式',
command: 'tauri build'
},
{
name: '🔙 返回上一步',
value: 'back',
description: '返回平台选择',
command: null
}
]
case 'android':
return [
{
name: '📱 apk 安装包',
value: 'apk',
description: '生成 Android APK 安装包',
command: 'tauri android build'
},
{
name: '🔙 返回上一步',
value: 'back',
description: '返回平台选择',
command: null
}
]
case 'ios':
return [
{
name: '📱 IOS 应用',
value: 'ios',
description: '生成 IOS 应用包',
command: 'tauri ios build --export-method app-store-connect'
},
{
name: '🔙 返回上一步',
value: 'back',
description: '返回平台选择',
command: null
}
]
default:
return []
}
}
// 获取调试模式选项
function getDebugOptions() {
return [
{
name: '🚀 正式版本',
value: 'release',
description: '生成正式版本',
isDebug: false
},
{
name: '🔧 调试版本',
value: 'debug',
description: '生成调试版本 (可弹出控制台)',
isDebug: true
},
{
name: '🔙 返回上一步',
value: 'back',
description: '返回包格式选择',
isDebug: null
}
]
}
// 执行打包命令
async function executeBuild(command, isDebug = false) {
// 如果是调试模式,添加 --debug 参数
const finalCommand = isDebug ? `${command} --debug` : command
const [cmd, ...args] = finalCommand.split(' ')
const child = spawn(cmd, args, {
stdio: 'inherit', // 直接继承父进程的 stdio,保留颜色输出
shell: true
})
return new Promise((resolve, reject) => {
child.on('close', (code) => {
if (code === 0) {
console.log('\n🎉 打包完成')
resolve(code)
} else {
console.log(`\n❌ 打包失败,退出代码: ${code}`)
resolve(code)
}
})
child.on('error', (error) => {
console.error(`\n❌ 执行错误: ${error.message}`)
reject(error)
})
})
}
// 选择平台的函数
async function selectPlatform() {
const platformOptions = getPlatformOptions()
const selectedPlatform = await select({
message: '请选择要打包的平台:',
choices: platformOptions.map((option) => ({
name: option.name,
value: option.value,
description: `\x1b[90m${option.description}\x1b[0m`
})),
pageSize: 8,
loop: false
})
if (selectedPlatform === 'cancel') {
console.log('\n👋 已取消打包')
process.exit(0)
}
return { selectedPlatform, platformOptions }
}
// 选择调试模式的函数
async function selectDebugMode() {
const debugOptions = getDebugOptions()
const selectedDebug = await select({
message: '第三步:请选择版本类型:',
choices: debugOptions.map((option) => ({
name: option.name,
value: option.value,
description: `\x1b[90m${option.description}\x1b[0m`
})),
pageSize: 4,
loop: false
})
if (selectedDebug === 'back') {
return 'back'
}
const selectedOption = debugOptions.find((option) => option.value === selectedDebug)
return selectedOption.isDebug
}
// 选择包格式的函数
async function selectBundle(selectedPlatform) {
const bundleOptions = getBundleOptions(selectedPlatform)
if (bundleOptions.length === 0) {
console.log('\n❌ 该平台暂不支持')
return 'back' // 返回平台选择
}
const selectedBundle = await select({
message: `请选择${selectedPlatform}的打包格式:`,
choices: bundleOptions.map((option) => ({
name: option.name,
value: option.value,
description: `\x1b[90m${option.description}\x1b[0m`
})),
pageSize: 6,
loop: false
})
if (selectedBundle === 'back') {
return 'back' // 返回上一步
}
// 找到选中的选项
const selectedOption = bundleOptions.find((option) => option.value === selectedBundle)
if (!selectedOption || !selectedOption.command) {
console.log('\n👋 已取消打包操作')
process.exit(0)
}
return selectedOption
}
async function main() {
try {
// 主循环
while (true) {
// 第一步:选择平台
const { selectedPlatform } = await selectPlatform()
// 第二步:选择包格式
while (true) {
const bundleResult = await selectBundle(selectedPlatform)
// 如果返回 'back',返回平台选择
if (bundleResult === 'back') {
break
}
// 移动端平台(iOS 和 Android)直接打包正式版本,不需要选择调试模式
const isMobilePlatform = selectedPlatform === 'ios' || selectedPlatform === 'android'
if (isMobilePlatform) {
const exitCode = await executeBuild(bundleResult.command, false)
process.exit(exitCode)
} else {
// 桌面端平台需要选择调试模式
// 第三步:选择调试模式
while (true) {
const debugResult = await selectDebugMode()
// 如果返回 'back',返回包格式选择
if (debugResult === 'back') {
break
}
const exitCode = await executeBuild(bundleResult.command, debugResult)
process.exit(exitCode)
}
}
}
}
} catch (error) {
if (error.name === 'ExitPromptError') {
// 用户按了 Ctrl+C
console.log('\n👋 已取消操作')
process.exit(0)
} else {
console.error('发生错误:', error)
process.exit(1)
}
}
}
main()