UNPKG

mtl-cli

Version:
1,131 lines (949 loc) 38.4 kB
const shell = require('shelljs'); const fs = require('fs-extra'); const path = require('path'); const inquirer = require('inquirer'); const utils = require('./mtl').Utils; const xml2js = require('xml2js'); const configFile = require('./config'); const os = require("os"); var unzip = require("unzip-stream"); const Configstore = require('configstore'); const conf = new Configstore(configFile.CONFIG_STORE_FILENAME); const PORT = 3000; // long-running process running on this, e.g. a web-server. const { kill } = require("cross-port-killer"); // var crypto = require('crypto'); // var md5 = crypto.createHash('md5'); const chokidar = require('chokidar'); const { spawn } = require('child_process'); const debugList = [{ type: 'list', message: '请选择项目平台:1、iOS;2、Android ;3、WX ;4、DD, 用上下箭头选择平台:', name: 'platform', choices: [ "iOS", "android", "WX", "DD" ], filter: function (val) { // 使用filter将回答变为小写 return val.toLowerCase(); } }]; var start = function (platform) { if (!utils.isProject()) { return utils.reportError("不是MTL工程目录") } let plat = utils.checkPlatform(platform); if (utils.isError(plat)) { inquirer.prompt(debugList).then(answers => { beginDebug(answers.platform); }); } else { beginDebug(plat); } return utils.SUCCESS; } //调试代码的正式入口 function beginDebug(plat) { console.log('选用平台:' + plat); //utils.copyHosts("debug"); switch (plat) { case utils.Platform.IOS: return startIOS(); case utils.Platform.ANDROID: return startAndroid(); case utils.Platform.WEIXIN: return startWX(); case utils.Platform.DingDing: return startDD(); } utils.reportError("不支持的平台 - " + plat); } function chokidarWatch() { let dir = shell.pwd() + "/app/"; // Initialize watcher. const watcher = chokidar.watch(dir, { ignored: /(^|[\/\\])\../, persistent: true }); // Something to use when events are received. const log = console.log.bind(console); // Add event listeners. watcher .on('add', function (path) { // log('File', path, 'has been added'); }) .on('addDir', function (path) { // log('Directory', path, 'has been added'); }) .on('change', function (path) { log('File', path, 'has been changed'); var start = 0; var pwd = shell.pwd().split(path.sep).join('/'); if(utils.isWindows()){ // win console.log("WIN 系统"); start = path.indexOf("\\app\\"); }else{ // mac console.log("MAC 系统"); start = path.indexOf("/app/"); } console.log("文件目录起始位置:" + start); let relativeFileDir = path.substring(start); console.log("目的修改文件的相对文件路径:" + relativeFileDir); if (fs.existsSync(shell.pwd() + "/output/wx/debug/proj/project.config.json")) { // copyAndDebugWeixin("false"); let absoluteFileDir = pwd + "/output/wx/debug" + relativeFileDir; console.log("wx目的修改文件的绝对文件路径:" + absoluteFileDir); fs.copySync(path, absoluteFileDir); } if (fs.existsSync(shell.pwd() + "/output/ios/debug/debug.app")) { copyAndInstallDebugIOS("false"); let absoluteFileDir = pwd + "/output/ios/debug" + relativeFileDir; console.log("ios目的修改文件的绝对文件路径:" + absoluteFileDir); fs.copySync(path, absoluteFileDir); } if (fs.existsSync(shell.pwd() + "/output/android/debug/debug.apk")) { let absoluteFileDir = pwd + "/output/android/debug" + relativeFileDir; console.log("android目的修改文件的绝对文件路径:" + absoluteFileDir); fs.copySync(path, absoluteFileDir); // copyAndInstallDebugAndroid("false"); } if (fs.existsSync(shell.pwd() + "/output/dd/debug/proj/app.js")) { let absoluteFileDir = pwd + "/output/dd/debug" + relativeFileDir; console.log("dd目的修改文件的绝对文件路径:" + absoluteFileDir); fs.copySync(path, absoluteFileDir); // copyAndDebugDD("false"); } }) const watcherProjectJson = chokidar.watch(shell.pwd() + "/project.json", { ignored: /(^|[\/\\])\../, persistent: true }); watcherProjectJson .on('add', function (path) { // log('File', path, 'has been added'); }) .on('addDir', function (path) { // log('Directory', path, 'has been added'); }) .on('change', function (path) { log('File', path, 'has been changed'); let pwd = shell.pwd().split(path.sep).join('/'); if (fs.existsSync(shell.pwd() + "/output/wx/debug/proj/project.config.json")) { // copyAndDebugWeixin("false"); let absoluteFileDir = pwd + "/output/wx/debug/app/project.json"; console.log("wx目的修改文件的绝对文件路径:" + absoluteFileDir); fs.copySync(path, absoluteFileDir); } if (fs.existsSync(shell.pwd() + "/output/ios/debug/debug.app")) { // copyAndInstallDebugIOS("false"); let absoluteFileDir = pwd + "/output/ios/debug/app/project.json"; console.log("ios目的修改文件的绝对文件路径:" + absoluteFileDir); fs.copySync(path, absoluteFileDir); } if (fs.existsSync(shell.pwd() + "/output/android/debug/debug.apk")) { // copyAndInstallDebugAndroid("false"); let absoluteFileDir = pwd + "/output/android/debug/app/project.json"; console.log("android目的修改文件的绝对文件路径:" + absoluteFileDir); fs.copySync(path, absoluteFileDir); } if (fs.existsSync(shell.pwd() + "/output/dd/debug/proj/app.js")) { let absoluteFileDir = pwd + "/output/dd/debug/app/project.json"; console.log("dd目的修改文件的绝对文件路径:" + absoluteFileDir); fs.copySync(path, absoluteFileDir); // copyAndDebugDD("false"); } // 更新云端project.json 文件 // zipFileAndUploadcloud(path,"true"); // uploadFileToCloud(path,"true"); }) } function chokidarWatchOutputDebugDir(platform) { var dir = null; console.log("chokidarWatchOutputDebugDir_platform==" + platform); switch (platform) { case utils.Platform.IOS: dir = shell.pwd() + "/output/ios/debug/app/"; break; case utils.Platform.ANDROID: dir = shell.pwd() + "/output/android/debug/app/"; break; case utils.Platform.WEIXIN: dir = shell.pwd() + "/output/wx/debug/app/"; break; case utils.Platform.DingDing: dir = shell.pwd() + "/output/dd/debug/app/"; break; } // Initialize watcher. const watcher = chokidar.watch(dir, { ignored: /(^|[\/\\])\../, persistent: true }); // Something to use when events are received. const log = console.log.bind(console); // Add event listeners. watcher .on('add', function (path) { // log('File', path, 'has been added'); }) .on('addDir', function (path) { // log('Directory', path, 'has been added'); }) .on('change', function (path) { log('outputFile', path, 'has been changed'); }) } function updateIosPlistFile(plistDir) { var plist = require('simple-plist'); // var data = plist.readFileSync(plistDir); var data = JSON.parse(JSON.stringify(plist.readFileSync(plistDir))); data.CFBundleIdentifier = "com.cscec3.mdmpush"; console.log(" data.CFBundleIdentifier:" + data.CFBundleIdentifier); console.log("end:::::readFileSync data:" + JSON.stringify(data)); // Write data to a plist file (synchronous) plist.writeFileSync(plistDir, data); } function startIOS() { if (os.platform() != "darwin") { console.log("ios debug调试程序必须在苹果电脑系统下运行!!!"); return; } // 监听工程源码 ,给debug 实时更新 chokidarWatch(); // 启动debug 程序 let pwd = shell.pwd().split(path.sep).join('/'); // 第一次启动debug 开始下载debug 程序 if (!fs.existsSync(pwd + "/iOSDebug/debug.app")) { if (conf.get('localResource') == "true") { fs.copySync(configFile.CONFIG_IOS_DEBUG_PATH , "./iOSDebug"); } else { console.log("开始下载android调试程序,请稍后..."); let debugLibs = require("../res/debug.json"); shell.exec("git clone " + debugLibs.iOSDebug + " --progress "); } } copyAndInstallDebugIOS("true"); // } } // xcrun instruments -w 'iPhone 6 Plus' // 在已经启动好的模拟器中安装应用: // xcrun simctl install booted Calculator.app (这里要特别注意,是app,不是ipa 安装时需要提供的是APP的文件路径) // 例如:xcrun simctl install booted /Users/xiexuemei/Downloads/DingTalk.app // const debugPath = __dirname + "/../res/"; function startAndroid() { let pwd = shell.pwd().split(path.sep).join('/'); // 第一次启动debug 开始下载debug 程序 if (!fs.existsSync(pwd + "/androidDebug/debug.apk")) { if (conf.get('localResource') == "true") { fs.copySync(configFile.CONFIG_ANDROID_DEBUG_PATH , "./androidDebug"); } else { console.log("开始下载android调试程序,请稍后..."); let debugLibs = require("../res/debug.json"); shell.exec("git clone " + debugLibs.androidDebug + " --progress "); } } chokidarWatch(); copyAndInstallDebugAndroid("true"); // } } // const cmdRunDebugApk = "adb shell am start -S com.yyiuap.summer.preview/com.yyuap.summer.core2.SummerWelcomeActivity"; // const adrAppPath="/sdcard/Android/data/com.yyiuap.summer.preview/preview_android/"; const cmdRunDebugApk = "adb shell am start -S com.yonyou.mtlandroid.debug/com.yonyou.myapis.DebugActivity"; const adrAppPath = "/sdcard/Android/data/com.yonyou.mtlandroid/preview_android/"; // var cmd = "adb install -r " + debugApk; // shell.exec(cmd); function runDebugAndroid(objPath) { //运行apk var cmd = "adb push " + objPath + "* " + adrAppPath + "www/"; shell.exec(cmd); //console.log("push->" + cmd); cmd = "adb push " + objPath + "/project.json " + adrAppPath; shell.exec(cmd); //console.log("push->" + cmd); shell.exec(cmdRunDebugApk); } function copyAndInstallDebugIOS(isStartNode) { let path = getPathByPlatform(utils.Platform.IOS); let objPath = "./" + path + "/"; copyProjectToOutput(objPath, utils.Platform.IOS); var debugApp = "./" + path + "/../debug.app"; if (!fs.existsSync(debugApp)) { let pwd = shell.pwd().split(path.sep).join('/'); // let cloudDebugApkPath = pwd + "/output/android/debug/export/debug.apk"; fs.copySync(pwd + "/iOSDebug/debug.app", debugApp); // fs.copySync(__dirname.split(path.sep).join('/') + '/../res/android/debug.apk', debugApk); } if (isStartNode == "true") { shell.exec("open \"/Applications/Xcode.app/Contents/Developer/Applications/Simulator.app/\""); // let debugApp = "./" + path + "/../debug.app"; // if(!fs.existsSync(debugApp)) { console.log("开始安装调试应用"); // let cmd = "cp -rf "+debugPath+"debug.app " + debugApp; // shell.exec(cmd); let cmdInstallApp = "xcrun simctl install booted " + debugApp; shell.exec(cmdInstallApp); // } console.log("开始运行调试应用"); shell.exec("xcrun simctl launch booted \"com.cscec3.mdmpush\""); // zipAndUploadcloud("ios"); let appJs = createAppJsFile(path); if (fs.exists(appJs, function (exists) { if (!exists) { return utils.reportError("没有找到app-node.js"); } startNode(appJs); })); } else { console.log("请到iOS模拟器刷新进行调试"); } return utils.SUCCESS; } function copyAndInstallDebugAndroid(isStartNode) { let path = getPathByPlatform(utils.Platform.ANDROID); let objPath = "./" + path + "/"; copyProjectToOutput(objPath, utils.Platform.ANDROID); let debugApk = "./" + path + "/../debug.apk"; if (!fs.existsSync(debugApk)) { let pwd = shell.pwd().split(path.sep).join('/'); fs.copySync(pwd + "/androidDebug/debug.apk", debugApk); } console.log("开始安装debug 调试程序"); //shell.exec(cmd); shell.exec("adb install -r " + debugApk); if (isStartNode == "true") { let appJs = createAppJsFile(path); if (fs.exists(appJs, function (exists) { if (!exists) { return utils.reportError("没有找到app-node.js"); } startNode(appJs); })); setTimeout(function () { shell.exec(cmdRunDebugApk); }, 5000); // zipAndUploadcloud("android"); } else { shell.exec(cmdRunDebugApk); console.log("请到android刷新进行调试"); } } function copyAndDebugWeixin(isStartNode) { console.log("准备开始生成微信工程..."); let path = getPathByPlatform(utils.Platform.WEIXIN); let objPath = "./" + path + "/"; let wxproj = objPath + "../proj/"; fs.ensureDirSync(objPath); fs.ensureDirSync(wxproj); // 拷贝 添加页面到 wx/proj 目录下 // fs.copySync(__dirname.split(path.sep).join('/')+ '/../res/debug.wx/', wxproj); if (!fs.existsSync(wxproj + "/app.json")) { fs.copySync(__dirname.split(path.sep).join('/') + '/../res/debug.wx/', wxproj); console.log("WX proj 工程创建完毕!"); } else { console.log("WX proj 工程已经存在!"); } let projPath = "output/" + utils.Platform.WEIXIN + "/debug/proj/"; fs.ensureDirSync(projPath); if (fs.existsSync("./wx/")) { //shell.exec("cp -rf ./wx/* " + projPath); //复制wx mdd页面到工程 fs.copySync('./wx/', projPath); } copyProjectToOutput(objPath, utils.Platform.WEIXIN); // if(isStartNode=="true"){ // zipAndUploadcloud("wx"); // }else{ // console.log("请到微信小程序工具刷新进行调试"); // } if (isStartNode == "true") { let appJs = createAppJsFile(path); // console.log(appJs); if (fs.exists(appJs, function (exists) { if (!exists) { return utils.reportError("没有找到app.js"); } startNode(appJs); })); } else { console.log("请到微信小程序工具刷新进行调试"); } // 开始上传云端 10.3.13.7 服务器debugger } function copyAndDebugDD(isStartNode) { console.log("准备开始生成钉钉工程..."); let path = getPathByPlatform(utils.Platform.DingDing); let objPath = "./" + path + "/"; let ddproj = objPath + "../proj/"; fs.ensureDirSync(objPath); fs.ensureDirSync(ddproj); // 拷贝 添加页面到 dd/proj 目录下 if (!fs.existsSync(ddproj + "/app.json")) { fs.copySync(__dirname.split(path.sep).join('/') + '/../res/debug.dd/', ddproj); console.log("DD proj 工程创建完毕!"); } else { console.log("DD proj 工程已经存在!"); } let projPath = "output/" + utils.Platform.DingDing + "/debug/proj/"; fs.ensureDirSync(projPath); if (fs.existsSync("./dd/")) { //复制dd 页面到工程 fs.copySync('./dd/', projPath); } copyProjectToOutput(objPath, utils.Platform.DingDing); if (isStartNode == "true") { let appJs = createAppJsFile(path); // console.log(appJs); if (fs.exists(appJs, function (exists) { if (!exists) { return utils.reportError("没有找到app.js"); } startNode(appJs); })); // zipAndUploadcloud("dd"); } else { console.log("请到钉钉小程序工具刷新进行调试"); } } function zipDir(platform) { var archiver = require('archiver'); var output = fs.createWriteStream('app.zip'); let archive = archiver('zip', { zlib: { level: 9 } // 设置压缩级别 }) // 存档警告 archive.on('warning', function (err) { if (err.code === 'ENOENT') { console.warn('stat故障和其他非阻塞错误') } else { throw err } }) // listen for all archive data to be written output.on('close', function () { console.log(archive.pointer() + ' total bytes'); console.log('archiver has been finalized and the output file descriptor has closed.'); uploadAppCloud(platform); }); // 存档出错 archive.on('error', function (err) { throw err }) archive.pipe(output); // 从子目录追加文件并将其命名为“新子dir”在存档中 var dir = null; switch (platform) { case utils.Platform.IOS: dir = "./output/ios/debug/app/"; break; case utils.Platform.ANDROID: dir = "./output/android/debug/app/"; break; case utils.Platform.WEIXIN: dir = "./output/wx/debug/app/"; break; case utils.Platform.DingDing: dir = "./output/dd/debug/app/"; break; } archive.directory(dir, 'app') archive.finalize(); } function zipFile(filePath, isProjectJson) { var archiver = require('archiver'); var output = fs.createWriteStream('file.zip'); let archive = archiver('zip', { zlib: { level: 9 } // 设置压缩级别 }) // 存档警告 archive.on('warning', function (err) { if (err.code === 'ENOENT') { console.warn('stat故障和其他非阻塞错误') } else { throw err } }) // listen for all archive data to be written output.on('close', function () { console.log(archive.pointer() + ' total bytes'); console.log('archiver has been finalized and the output file descriptor has closed.'); uploadFileToCloud(filePath, isProjectJson); }); // 存档出错 archive.on('error', function (err) { throw err }) archive.pipe(output); let FileNameStart = filePath.lastIndexOf("/", filePath.length - 1); let FileName = filePath.substring(FileNameStart + 1); console.log("文件名称:" + FileName); archive.file(filePath, { name: FileName }); archive.finalize(); } function uploadFileToCloud(filePath, isProjectJson) { var FormData = require('form-data'); var http = require('https'); var form = new FormData(); var file = "project.json"; var result = JSON.parse(fs.readFileSync(file)); var projectName = result.config.projectName; // var startPage = result.config.startPage; var gitUrl = result.config.gitUrl; form.append('appId', projectName); // 处理文件目录 if (isProjectJson == "true") { // 处理projectjson 文件 form.append('path', "/app/"); } else { // 工程源码文件 let end = filePath.lastIndexOf("/", filePath.length - 1); let start = filePath.indexOf("/app/"); console.log("文件目录起始位置:" + start); console.log("文件目录结束位置:" + end); let cloudFilePath = filePath.substring(start, end + 1); console.log("云端调试文件路径:" + cloudFilePath); form.append('path', cloudFilePath); } // form.append('startPage',projectName+"/app/"+startPage); form.append('file', fs.createReadStream("./file.zip")); //大文件时读取不全。 form.append("Content-Type", "application/x-www-form-urlencoded"); var headers = form.getHeaders();//这个不能少 var request = http.request({ method: 'POST', hostname: 'mdoctor.yonyoucloud.com', path: '/mtldebugger/mtl/file/uploadZip', headers: headers }, (res) => { res.on('data', (buffer) => { console.log("data=" + buffer); // 删除压缩文件 fs.removeSync('file.zip'); // var responseResult=JSON.parse(buffer); // if(responseResult.msg="success"){ // } }); res.on('end', () => { console.log("end"); }); }); request.on('error', (e) => { console.log(`problem with request: ${e.message}`); }); form.pipe(request); } function uploadAppCloud(platform) { // var FormData = require('form-data'); // var https = require('https'); // var form = new FormData(); // var file="project.json"; // var result=JSON.parse(fs.readFileSync(file)); // var projectName = result.config.projectName; // form.append('file', fs.createReadStream("./app.zip",{encoding:"utf8"})); // form.append('appid',projectName); // form.append('path',"sdfsdaf"); // var headers = form.getHeaders();//这个不能少 // var httpsRequest = require('https-request'); // var options = { // hostname: 'mdoctor.yonyoucloud.com', // path: '/mtldebugger/mtl/file/upload' // }; // var request = httpsRequest(options, headers, form, function(err, data){ // if(!err){ // console.log(data); // }else{ // console.log(err); // } // }); var FormData = require('form-data'); var http = require('https'); var form = new FormData(); var file = "project.json"; var result = JSON.parse(fs.readFileSync(file)); var projectName = result.config.projectName; var startPage = result.config.startPage; var gitUrl = result.config.gitUrl; form.append('appId', projectName); form.append('path', projectName + "/app"); // form.append('startPage',projectName+"/app/"+startPage); form.append('file', fs.createReadStream("./app.zip")); form.append("Content-Type", "application/x-www-form-urlencoded"); var headers = form.getHeaders();//这个不能少 var request = http.request({ method: 'POST', hostname: 'mdoctor.yonyoucloud.com', path: '/mtldebugger/mtl/file/uploadApp', headers: headers }, (res) => { res.on('data', (buffer) => { console.log("data=" + buffer); var responseResult = JSON.parse(buffer); if (responseResult.msg = "success") { // 打开浏览器 ,形成二维码 var openbrowser = require('openbrowser'); openbrowser("https://mdoctor.yonyoucloud.com/mtldebugger/mtl/qr/build?code=https://mdoctor.yonyoucloud.com/debugger/" + projectName + "/app/" + startPage); // 开始监听output debug 工程 // chokidarWatchOutputDebugDir(platform); // 删除压缩文件 fs.removeSync('file.zip'); } }); res.on('end', () => { console.log("end"); }); }); request.on('error', (e) => { console.log(`problem with request: ${e.message}`); }); form.pipe(request); } function zipAndUploadcloud(selectedPlatform) { (async function () { try { await zipDir(selectedPlatform); } catch (e) { console.log(e) } })(); } function zipFileAndUploadcloud(filePath, isProjectJson) { (async function () { try { await zipFile(filePath, isProjectJson); } catch (e) { console.log(e) } })(); } function cloudBuildAndUnzip(selectedPlatform) { // 接口请求 var FormData = require('form-data'); var http = require('http'); var form = new FormData(); var file = "project.json"; var result = JSON.parse(fs.readFileSync(file)); var projectName = result.config.projectName; var gitUrl = result.config.gitUrl; form.append('userName', 'ump'); form.append('buildType', selectedPlatform); // form.append('certName',certName); form.append('certName', ''); // form.append('request', fs.createReadStream("./test.zip"));//'request'是服务器接受的key form.append('projectName', projectName); form.append('gitUrl', gitUrl); form.append('gitBranch', ''); form.append('isDebug', "true"); var headers = form.getHeaders();//这个不能少 // headers.Cookie = cookie;//自己的headers属性在这里追加 var request = http.request({ method: 'POST', host: configFile.CONFIG_BUILDSERVER_URL, port: configFile.CONFIG_BUILDSERVER_PORT, path: configFile.CONFIG_BUILDPROJECT_API, headers: headers }, (res) => { var outFile = selectedPlatform + 'Debug.zip' let ws = fs.createWriteStream(outFile, { highWaterMark: 1 }) res.on('data', (buffer) => { ws.write(buffer); }); res.on('end', () => { //文件下载结束 ws.end(); if (selectedPlatform == 'android') { fs.exists("androidDebug.zip", function (exists) { if (exists) { // 删除已有的文件 fs.removeSync('./output/android/debug'); (async function () { try { await unzipSync('androidDebug.zip', './output/android/debug') // 获取android 目录下的文件目录 let pwd = shell.pwd().split(path.sep).join('/'); let filePath = pwd + "/output/android/debug"; let filesDir = getFilesDir(filePath); // 验证android目录文件 let len = filesDir.length; let apkPath; for (let i = 0; i < len; ++i) { if (filesDir[i].indexOf(".apk") >= 0) { apkPath = filesDir[i]; } } if (apkPath != null) { let debugApkPath = filePath + '/export/debug.apk'; fs.move(apkPath, debugApkPath, function (err) { if (err) return console.error(err) console.log('android 云端构建调试程序完成 🎉 🎉 🎉 !'); copyAndInstallDebugAndroid("true"); }); } else { console.log('android 云端构建调试程序失败 😢 😢 😢 !'); } } catch (e) { console.log(e) } })(); fs.removeSync('androidDebug.zip'); } if (!exists) { console.log("android 云端构建调试程序失败 😢 😢 😢 !"); } }) } else { fs.exists("iosDebug.zip", function (exists) { if (exists) { // 删除已有的文件 fs.removeSync('output/ios/debug'); (async function () { try { await unzipSync('iosDebug.zip', './output/ios/debug') // 生成debug APP 程序 let pwd = shell.pwd().split(path.sep).join('/'); let projectDir = pwd + "/output/ios/debug/export"; updateIosPlistFile(projectDir + "/" + projectName + "/" + projectName + "-info.plist"); // 在npm 包res/ios目录中copy AppDelegate.m ViewController.m 到调试程序中 fs.copySync(__dirname.split(path.sep).join('/') + '/../res/ios/', projectDir + "/" + projectName + "/Classes/"); // xcodebuild debug 工程 let workspaceDir = projectDir + "/" + projectName + ".xcworkspace"; let cmd = "xcodebuild -workspace " + workspaceDir + " -scheme " + projectName + " -sdk iphonesimulator12.2"; shell.exec(cmd); let derivedDataDir = os.homedir() + "/Library/Developer/Xcode/DerivedData/"; // 获取DerivedData目录下的目录列表 let componentsList = []; const files = fs.readdirSync(derivedDataDir); files.forEach(function (item, index) { let stat = fs.lstatSync(derivedDataDir + item); if (stat.isDirectory() === true) { componentsList.push(item); } }) // 获取iOS debug.app 目录 let len = componentsList.length; var debugAppPath; for (let i = 0; i < len; ++i) { if (componentsList[i].indexOf(projectName + "-") >= 0) { debugAppPath = derivedDataDir + componentsList[i] + "/Build/Products/Debug-iphonesimulator/" + projectName + ".app"; } } // debug app 程序移动指定output 目录 if (debugAppPath != null) { let pwd = shell.pwd().split(path.sep).join('/'); fs.move(debugAppPath, pwd + "/output/ios/debug/debug.app", function (err) { if (err) return console.error(err) // 执行 debug 程序 copyAndInstallDebugIOS("true"); }); } else { console.log('云端ios构建调试程序失败'); } } catch (e) { console.log(e) } })(); fs.removeSync('iosDebug.zip'); } if (!exists) { console.log("云端构建调试程序失败"); } }) } }); }); request.on('error', (e) => { console.log(`problem with request: ${e.message}`); }); form.pipe(request); } /** * 格式化输出JSON对象,返回String * @param {String} fileName * @param {String} mbDir */ function unzipSync(fileName, mbDir) { return new Promise((resolve, reject) => { fs.createReadStream(fileName).pipe(unzip.Extract({ path: mbDir })).on('close', () => { console.log('stream close') resolve() }).on('error', (err) => { reject(err) }) }) } function getFilesDir(filePath) { // console.log('filePath:'+filePath); var join = require('path').join; let filesDir = []; function findFile(path) { let files = fs.readdirSync(path); files.forEach(function (item, index) { let fPath = join(path, item); let stat = fs.statSync(fPath); if (stat.isDirectory() === true) { findFile(fPath); } if (stat.isFile() === true) { filesDir.push(fPath); } }); } findFile(filePath); // console.log(filesDir); return filesDir; } function updateConfigFileToDebug() { // 修改project.json var proj = JSON.parse(fs.readFileSync("./project.json").toString()); // proj.config.appName ="快速预览"; // proj.config.packageName="com.yyiuap.summer.preview"; proj.config.debuggerEnable = "true"; // proj.config.packageName ="com.yonyou.mtl.debugger"; fs.writeFileSync("./project.json", formatJson(proj), { flag: 'w', encoding: 'utf-8', mode: '0666' }); //修改./app/config.xml // let xmlFile = "./app/config.xml"; // var builder = new xml2js.Builder(); // var xml = builder.buildObject(proj); // fs.writeFileSync(xmlFile, xml, { flag: 'w', encoding: 'utf-8', mode: '0666' }); } /** * MTL工程 提交远程仓库 * */ function commitAndPushConfigFile() { let pwd = shell.pwd().split(path.sep).join('/'); console.log('调试程序源码正在整理中,请稍候 🚀 🚀 🚀 ...'); if (!fs.existsSync(".git")) { return utils.reportError("未找到远程git仓库 ,请执行: mtl pushRemote 命令创建远程代码托管后,再进行debug。 "); } //first commit shell.exec("git add -A"); shell.exec("git commit -m update -q"); shell.exec("git push"); return utils.SUCCESS; } /** * 格式化输出JSON对象,返回String * @param {JSON} data */ function formatJson(data) { let LN = "\r"; let TAB = "\t"; var rep = "~"; var jsonStr = JSON.stringify(data, null, rep) var str = ""; for (var i = 0; i < jsonStr.length; i++) { var text2 = jsonStr.charAt(i) if (i > 1) { var text = jsonStr.charAt(i - 1) if (rep != text && rep == text2) { str += LN } } str += text2; } jsonStr = ""; for (var i = 0; i < str.length; i++) { var text = str.charAt(i); if (rep == text) jsonStr += TAB; else { jsonStr += text; } if (i == str.length - 2) jsonStr += LN } return jsonStr; } //开始调试微信Web小程序 function startWX() { // console.log("准备开始生成微信工程..."); // let path = getPathByPlatform(utils.Platform.WEIXIN); // let objPath = "./" + path +"/"; // let wxproj = objPath + "../proj/"; // fs.ensureDirSync(objPath); // fs.ensureDirSync(wxproj); // // 拷贝 添加页面到 wx/proj 目录下 // fs.copySync(__dirname.split(path.sep).join('/')+ '/../res/debug.wx/', wxproj); // let projPath = "output/" + utils.Platform.WEIXIN + "/debug/proj/"; // fs.ensureDirSync(projPath); // if(fs.existsSync("./wx/")) { // //shell.exec("cp -rf ./wx/* " + projPath); //复制wx mdd页面到工程 // fs.copySync('./wx/', projPath); // } // copyProjectToOutput(objPath,utils.Platform.WEIXIN); // let appJs = createAppJsFile(path); // // console.log(appJs); // if(fs.exists(appJs, function(exists) { // if(!exists) { // return utils.reportError("没有找到app.js"); // } // startNode(appJs); // })) // 监听工程源码 ,给debug 实时更新 chokidarWatch(); copyAndDebugWeixin("true"); return utils.SUCCESS; } //开始调试钉钉Web小程序 function startDD() { // 监听工程源码 ,给debug 实时更新 chokidarWatch(); copyAndDebugDD("true"); return utils.SUCCESS; } function getPathByPlatform(platform) { return "output/" + platform + "/debug/app"; } function copyProjectToOutput(objPath, platform) { //开始复制文件 fs.copySync('./app/', objPath); let pltPath = "./" + platform + "/"; if (fs.existsSync(pltPath)) { fs.copySync(pltPath, objPath); } fs.copySync('project.json', objPath + '/project.json'); } var cp1; async function startNode(appJs) { kill(PORT).then(pids => { console.log(pids); console.log("开始启动node"); //shell.exec("npm --save install express") // shell.exec("node " + appJs); cp1 = spawn('node', [appJs], { cwd: process.cwd(), env: process.env, detached: true, silent: true }); cp1.stdout.on('data', (data) => { console.log(`stdout: ${data}`); }); cp1.stderr.on('data', (data) => { console.log(`stderr: ${data}`); }); cp1.on('close', (code) => { console.log(`child process exited with code ${code}`); }); }) } function createAppJsFile(path) { let appJs = "./" + path + "/app-node.js"; if (!fs.existsSync(appJs)) { //创建appJs // console.log("正在为第一次启动作准备……"); // console.log(appJs); var content = "const express = require('express');\r"; content += "const app = express();\r"; content += "app.use(express.static('" + path + "'));\r"; content += "app.listen(3000, () => console.log('Debug the App listening on port 3000!'));"; fs.writeFileSync(appJs, content); console.log("app-node.js创建完成"); } return appJs; } exports.start = start