bia
Version:
a tool for download git repository
320 lines (298 loc) • 8.75 kB
JavaScript
const path = require('path')
const execa = require('execa')
const ora = require('ora')
const fse = require('fs-extra')
const table = require('console.table')
const question = require('./question')
const IOS_CONFIG = require('../../config/ios.json')
/**
* 格式化iphone列表
* @param {string} iphoneStr iphone的字符串列表
*/
const formatIphoneList = (iphoneStr) => {
let arr = iphoneStr.split('\n')
let iphoneList = []
let reg = new RegExp('^' + IOS_CONFIG.client.toLocaleLowerCase())
for (let i = 1; i < arr.length; i++) {
if (reg.test(arr[i].toLocaleLowerCase())) {
iphoneList.push(arr[i])
}
}
return iphoneList
}
/**
* 获取iphone的列表
*/
const getIphoneList = () => {
return new Promise((resolve, reject) => {
console.log('== 正在获取本地设备清单 ==')
console.log('-- 首次启动时间较长,请耐心等待... --')
const cmd = `xcrun instruments -w "${IOS_CONFIG.client}"`
execa.shell(cmd).then((res) => {
// 运行此命令会进入到异常中
let iphoneList = formatIphoneList(res.stderr)
if (iphoneList.length === 0) {
reject()
}
resolve(iphoneList.reverse())
}).catch(res => {
let iphoneList = formatIphoneList(res.stderr)
if (iphoneList.length === 0) {
reject()
}
resolve(iphoneList.reverse())
})
})
}
/**
* 启动指定 iphone 的 simulator
* @param {string} iphone 指定的iphone版本
*/
const startSimulator = (iphone) => {
return new Promise((resolve, reject) => {
const cmd = `xcrun instruments -w '${iphone}'`
execa.shell(cmd).then(() => {
resolve(iphone)
}).catch(() => {
reject(iphone)
})
})
}
/**
* 打开指定boundId的app
* @param {string} boundId 打开app的boundId
*/
const openAppByBoundId = (boundId) => {
return new Promise((resolve, reject) => {
let cmd = `xcrun simctl launch booted ${boundId}`
execa.shell(cmd).then(res => {
resolve(res)
}).catch(err => {
if (err.code === 163) {
getIphoneList().then(res => {
return question.chooseIphone(res)
}).then(res => {
return startSimulator(res)
}).then(() => {
return openAppByBoundId(boundId)
}, () => {
return openAppByBoundId(boundId)
}).catch(err => {
reject(err)
})
} else {
reject(err)
}
})
})
}
/**
* 用指定的scheme打开目标url
* @param {string} url 打开的目标地址
* @param {string} scheme 打开url的方式
*/
const openUrlByScheme = (url, scheme) => {
return new Promise((resolve, reject) => {
let newUrl = url
if (scheme) {
newUrl = `${scheme}${encodeURIComponent(url)}`
}
let cmd = `xcrun simctl openurl booted '${newUrl}'`
execa.shell(cmd).then(res => {
resolve(res)
}).catch(err => {
if (err.code === 163) {
getIphoneList().then(res => {
return question.chooseIphone(res)
}).then(res => {
return startSimulator(res)
}).then(() => {
return openUrlByScheme(url, scheme)
}, () => {
return openUrlByScheme(url, scheme)
}).catch(err => {
reject(err)
})
} else {
reject(err)
}
})
})
}
/**
* 移动文件
* @param {string} ori 源文件
* @param {string} dist 目标文件
*/
const moveFileToDist = (ori, dist) => {
return new Promise((resolve, reject) => {
try {
fse.copySync(ori, dist)
resolve(ori, dist)
} catch (err) {
reject(err)
}
})
}
/**
* 查看配置列表信息
*/
const showConfigList = () => {
return new Promise((resolve, reject) => {
try {
let tab = table.getTable(IOS_CONFIG.list)
console.log('\n')
console.log(tab)
resolve()
} catch (err) {
reject(err)
}
})
}
/**
* 更新配置文件
* @param {object} res 配置文件信息
*/
const updateConfig = (res) => {
return new Promise((resolve, reject) => {
let dist = path.resolve(__dirname, '../../config/ios.json')
let content = JSON.stringify(res, null, 4)
fse.outputFile(dist, content, err => {
if (err) {
reject(err)
} else {
resolve(res)
}
})
})
}
/**
* 获取配置文件的配置信息列表
*/
const getConfigList = () => {
return new Promise((resolve, reject) => {
if (IOS_CONFIG.list && IOS_CONFIG.list.length) {
let list = []
IOS_CONFIG.list.forEach((_v, _i) => {
list.push({
name: `${_v.name}: ${_v.cname}_${_v.packageName}`,
value: _i,
})
})
resolve(list)
} else {
reject('== 未配置任何的app列表,请先配置 ==')
}
})
}
/**
* 下载app
* @param {string} type
* @param {*} url
*/
const downloadApp = (type, url) => {
return new Promise((resolve, reject) => {
switch (type) {
case 'git': {
const spinner = ora('== 拼命下载中... ==')
const tplTemp = path.resolve(process.env.HOME, '.bia-init-applist', url.replace(/\/|:/g, '-'))
spinner.start()
fse.emptyDirSync(tplTemp)
let cmd = `git clone ${url} ${tplTemp}`
execa.shell(cmd).then(() => {
spinner.stop()
console.log('== 下载完成,开始安装... ==')
resolve(tplTemp)
}).catch(err => {
spinner.stop()
console.log('== 下载异常,停止安装 ==')
reject(err)
})
break
}
case 'other':
default: {
break
}
}
})
}
/**
* 安装app
* @param {string} ori app的目标地址
* @param {string} appName app包的名称
*/
const installApp = (ori, appName) => {
return new Promise((resolve, reject) => {
const spinner = ora('== 拼命安装中... ==')
spinner.start()
let appOri = path.resolve(ori, appName)
let cmd = `xcrun simctl install booted ${appOri}`
execa.shell(cmd).then(() => {
spinner.stop()
resolve(appName)
}).catch(err => {
spinner.stop()
if (err.code === 163) {
getIphoneList().then(res => {
return question.chooseIphone(res)
}).then(res => {
return startSimulator(res)
}).then(() => {
return installApp(ori, appName)
}, () => {
return installApp(ori, appName)
}).catch(err => {
reject(err)
})
} else {
reject(err)
}
})
})
}
/**
* 卸载app
* @param {string} boundId app的boundId
*/
const removeApp = (boundId) => {
return new Promise((resolve, reject) => {
const spinner = ora('== 拼命卸载中... ==')
spinner.start()
let cmd = `xcrun simctl uninstall booted ${boundId}`
execa.shell(cmd).then(() => {
spinner.stop()
resolve()
}).catch(err => {
spinner.stop()
if (err.code === 163) {
getIphoneList().then(res => {
return question.chooseIphone(res)
}).then(res => {
return startSimulator(res)
}).then(() => {
return removeApp(boundId)
}, () => {
return removeApp(boundId)
}).catch(err => {
reject(err)
})
} else {
reject(err)
}
})
})
}
module.exports = {
getIphoneList,
startSimulator,
openAppByBoundId,
openUrlByScheme,
moveFileToDist,
showConfigList,
updateConfig,
getConfigList,
downloadApp,
installApp,
removeApp,
}