UNPKG

bia

Version:

a tool for download git repository

320 lines (298 loc) 8.75 kB
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, }