diff --git a/src/scripts/json-tags-helper.js b/src/scripts/json-tags-helper.js index c09165d..7853827 100644 --- a/src/scripts/json-tags-helper.js +++ b/src/scripts/json-tags-helper.js @@ -18,6 +18,10 @@ function getWatchersDictionary(json) { return getDictionary(json["watch"]); } +function getBuildCommandsDictionary(json) { + return getDictionary(json["buildCommand"]); +} + function getDictionary(json) { var result = []; for (var i in json) { @@ -31,4 +35,5 @@ module.exports.getScriptsDictionary = getScriptsDictionary; module.exports.getDescriptionsDictionary = getDescriptionsDictionary; module.exports.getCategoriesDictionary = getCategoriesDictionary; module.exports.getShortCommandsDictionary = getShortCommandsDictionary; -module.exports.getWatchersDictionary = getWatchersDictionary; \ No newline at end of file +module.exports.getWatchersDictionary = getWatchersDictionary; +module.exports.getBuildCommandsDictionary = getBuildCommandsDictionary; \ No newline at end of file diff --git a/src/scripts/postinstall.js b/src/scripts/postinstall.js index f74f178..279cc3c 100644 --- a/src/scripts/postinstall.js +++ b/src/scripts/postinstall.js @@ -330,6 +330,7 @@ function writeToSrcJson(inputParams) { const devDepsTag = "devDependencies"; const descriptionsTag = "descriptions"; const shortCommandsTag = "shortCommands"; + const buildCommandsTag = "buildCommand" const categoriesTag = "categories"; var path = inputParams.pluginSrcFolder + "/package.json"; let jsonFile = fs.readFileSync(path); @@ -360,12 +361,14 @@ function writeToSrcJson(inputParams) { var ndJson = {}; var pluginScriptsJson = {}; var pluginDescriptionsJson = {}; - var pluginDShortCommandsJson = {}; + var pluginShortCommandsJson = {}; + var pluginBuildCommandJson = {}; var pluginCategoriesJson = {}; var pluginWatchJson = {}; var pluginScripts = updateScripts(predefinedScripts, pluginScriptsJson); var descriptions = updateDescriptions(predefinedScripts, pluginDescriptionsJson); - var shortCommands = updateShortCommands(predefinedScripts, pluginDShortCommandsJson); + var shortCommands = updateShortCommands(predefinedScripts, pluginShortCommandsJson); + var buildCommand = updateBuildCommands(predefinedScripts, pluginBuildCommandJson); var categories = updateCategories(predefinedScripts, pluginCategoriesJson); var pluginWatch = updateWatch(predefinedScripts, pluginWatchJson); ndJson[scriptsTag] = pluginScripts; @@ -373,6 +376,7 @@ function writeToSrcJson(inputParams) { ndJson[devDepsTag] = newDevDeps; ndJson[descriptionsTag] = descriptions; ndJson[shortCommandsTag] = shortCommands; + ndJson[buildCommandsTag] = buildCommand; ndJson[categoriesTag] = categories; var ndJsonPath = inputParams.pluginSrcFolder + "/node_modules/nativescript-dev-debugging/scripts/nd-package.json"; fs.writeFileSync(ndJsonPath, JSON.stringify(ndJson, null, "\t")); @@ -495,6 +499,14 @@ function updateShortCommands(scripts, jsonDevDeps) { return jsonDevDeps; } +function updateBuildCommands(scripts, jsonDevDeps) { + scripts.forEach((script) => { + jsonDevDeps[script.key] = script.buildCommand; + }); + + return jsonDevDeps; +} + function updateCategories(newDevDependencies, json) { newDevDependencies.forEach((dep) => { json[dep.key] = dep.category; diff --git a/src/scripts/predefined-scripts.js b/src/scripts/predefined-scripts.js index 1d933d5..3f4f255 100644 --- a/src/scripts/predefined-scripts.js +++ b/src/scripts/predefined-scripts.js @@ -46,64 +46,73 @@ function getPluginPreDefinedScripts(srcPath, demoFolder, demoAngularFolder, demo }, { key: "nd.demo.android", - value: "npm run nd.build.native.android && npm run nd.open.android.studio && npm run nd.demo.tns.run.android", + value: "npm run nd.open.android.studio && npm run nd.demo.tns.run.android", description: "Runs your 'demo' app and opens Android Studio. After that use 'Attach debugger to Android process (demo)' to debug the native source code", + buildCommand: "npm run nd.build.native.android", category: "android debug", shortCommands: ["demo android simulator attach", "demo android device attach"] }, { key: "nd.demo.ios", - value: "npm run nd.build.simulator.native.ios && npm run nd.open.xcode && npm run nd.demo.tns.run.ios", + value: "npm run nd.open.xcode && npm run nd.demo.tns.run.ios", description: "Runs your 'demo' app and opens Xcode. After that use 'Attach to process by PID or Name (demo)' to debug the native source code. (for simulator)", + buildCommand: "npm run nd.build.simulator.native.ios", category: "ios debug", shortCommands: ["demo ios simulator attach"] }, { key: "nd.demo.ios.device", - value: "npm run nd.build.device.native.ios && npm run nd.open.xcode && npm run nd.demo.tns.run.ios", + value: "npm run nd.open.xcode && npm run nd.demo.tns.run.ios", description: "Runs your 'demo' app and opens Xcode. After that use 'Attach to process by PID or Name (demo)' to debug the native source code. (for real device)", + buildCommand: "npm run nd.build.device.native.ios", category: "ios debug", shortCommands: ["demo ios device attach"] }, { key: "nd.demo.angular.android", - value: "npm run nd.build.native.android && npm run nd.open.android.studio && npm run nd.demo.angular.tns.run.android", + value: "npm run nd.open.android.studio && npm run nd.demo.angular.tns.run.android", description: "Runs your 'demo-angular' app and opens Android Studio. After that use 'Attach debugger to Android process (demo)' to debug the native source code", + buildCommand: "npm run nd.build.native.android", category: "android debug", shortCommands: ["demo-angular android simulator attach", "demo-angular android device attach"] }, { key: "nd.demo.angular.ios", - value: "npm run nd.build.simulator.native.ios && npm run nd.open.xcode && npm run nd.demo.angular.tns.run.ios", + value: "npm run nd.open.xcode && npm run nd.demo.angular.tns.run.ios", description: "Runs your 'demo-angular' app and opens Xcode. After that use 'Attach to process by PID or Name (demo)' to debug the native source code. (for simulator)", + buildCommand: "npm run nd.build.simulator.native.ios", category: "ios debug", shortCommands: ["demo-angular ios simulator attach"] }, { key: "nd.demo.angular.ios.device", - value: "npm run nd.build.device.native.ios && npm run nd.open.xcode && npm run nd.demo.angular.tns.run.ios", + value: "npm run nd.open.xcode && npm run nd.demo.angular.tns.run.ios", description: "Runs your 'demo-angular' app and opens Xcode. After that use 'Attach to process by PID or Name (demo)' to debug the native source code. (for real device)", + buildCommand: "npm run nd.build.device.native.ios", category: "ios debug", shortCommands: ["demo-angular ios device attach"] }, { key: "nd.demo.vue.android", - value: "npm run nd.build.native.android && npm run nd.open.android.studio && npm run nd.demo.vue.tns.run.android", + value: "npm run nd.open.android.studio && npm run nd.demo.vue.tns.run.android", description: "Runs your 'demo-vue' app and opens Android Studio. After that use 'Attach debugger to Android process (demo)' to debug the native source code", + buildCommand: "npm run nd.build.native.android", category: "android debug", shortCommands: ["demo-vue android simulator attach", "demo-vue android device attach"] }, { key: "nd.demo.vue.ios", - value: "npm run nd.build.simulator.native.ios && npm run nd.open.xcode && npm run nd.demo.vue.tns.run.ios", + value: "npm run nd.open.xcode && npm run nd.demo.vue.tns.run.ios", description: "Runs your 'demo-vue' app and opens Xcode. After that use 'Attach to process by PID or Name (demo)' to debug the native source code. (for simulator)", + buildCommand: "npm run nd.build.simulator.native.ios", category: "ios debug", shortCommands: ["demo-vue ios simulator attach"] }, { key: "nd.demo.vue.ios.device", - value: "npm run nd.build.device.native.ios && npm run nd.open.xcode && npm run nd.demo.vue.tns.run.ios", + value: "npm run nd.open.xcode && npm run nd.demo.vue.tns.run.ios", description: "Runs your 'demo-vue' app and opens Xcode. After that use 'Attach to process by PID or Name (demo)' to debug the native source code. (for real device)", + buildCommand: "npm run nd.build.device.native.ios", category: "ios debug", shortCommands: ["demo-vue ios device attach"] }, @@ -137,64 +146,11 @@ function getPluginPreDefinedScripts(srcPath, demoFolder, demoAngularFolder, demo description: "Rebuilds the plugin's native source code and opens it in Xcode. (for real device)", category: "secondary" }, - { - key: "nd.build.run.device.demo.app.ios", - value: "npm run nd.build.device.native.ios" + " && npm run nd.demo.tns.run.ios", - description: "Build the native code and executes 'tns run ios' for the 'demo' app", - category: "secondary" - }, - { - key: "nd.build.run.simulator.demo.app.ios", - value: "npm run nd.build.simulator.native.ios" + " && npm run nd.demo.tns.run.ios", - description: "Build the native code and executes 'tns run ios' for the 'demo' app", - category: "secondary" - }, - { - key: "nd.build.run.demo.app.android", - value: "npm run nd.build.native.android" + " && npm run nd.demo.tns.run.android", - description: "Build the native code and executes 'tns run android' for the 'demo' app", - category: "secondary" - }, - { - key: "nd.build.run.demo.angular.app.ios", - value: "npm run nd.build.device.native.ios " + " && npm run nd.demo.angular.tns.run.ios", - description: "Build the native code and executes 'tns run ios' for the 'demo angular' app", - category: "secondary" - }, - { - key: "nd.build.run.simulator.demo.angular.app.ios", - value: "npm run nd.build.simulator.native.ios " + " && npm run nd.demo.angular.tns.run.ios", - description: "Build the native code and executes 'tns run ios' for the 'demo angular' app", - category: "secondary" - }, - { - key: "nd.build.run.demo.angular.app.android", - value: "npm run nd.build.native.android " + " && npm run nd.demo.angular.tns.run.android", - description: "Build the native code and executes 'tns run android' for the 'demo angular' app", - category: "secondary" - }, - { - key: "nd.build.run.demo.vue.app.ios", - value: "npm run nd.build.device.native.ios " + " && npm run nd.demo.vue.tns.run.ios", - description: "Build the native code and executes 'tns run ios' for the 'demo vue' app", - category: "secondary" - }, - { - key: "nd.build.run.simulator.demo.vue.app.ios", - value: "npm run nd.build.simulator.native.ios " + " && npm run nd.demo.vue.tns.run.ios", - description: "Build the native code and executes 'tns run ios' for the 'demo vue' app", - category: "secondary" - }, - { - key: "nd.build.run.demo.vue.app.android", - value: "npm run nd.build.native.android " + " && npm run nd.demo.vue.tns.run.android", - description: "Build the native code and executes 'tns run android' for the 'demo vue' app", - category: "secondary" - }, { key: "nd.demo.run.watch.android", - value: "npm run nd.open.android.studio && npm run nd.build.run.demo.app.android", + value: "npm run nd.open.android.studio && npm run nd.demo.tns.run.android", shortCommands: ["demo android simulator attach & watch", "demo android device attach & watch"], + buildCommand: "npm run nd.build.native.android", patterns: [ androidSourcePath ], @@ -203,8 +159,9 @@ function getPluginPreDefinedScripts(srcPath, demoFolder, demoAngularFolder, demo }, { key: "nd.demo.run.watch.ios", - value: "npm run nd.open.xcode && npm run nd.build.run.simulator.demo.app.ios", + value: "npm run nd.open.xcode && npm run nd.demo.tns.run.ios", shortCommands: ["demo ios simulator attach & watch"], + buildCommand: "npm run nd.build.simulator.native.ios", patterns: [ iosSourcePath ], @@ -212,8 +169,9 @@ function getPluginPreDefinedScripts(srcPath, demoFolder, demoAngularFolder, demo }, { key: "nd.demo.run.watch.device.ios", - value: "npm run nd.open.xcode && npm run nd.build.run.device.demo.app.ios", + value: "npm run nd.open.xcode && npm run npm run nd.demo.tns.run.ios", shortCommands: ["demo ios device attach & watch"], + buildCommand: "npm run nd.build.device.native.ios", patterns: [ iosSourcePath ], @@ -221,8 +179,9 @@ function getPluginPreDefinedScripts(srcPath, demoFolder, demoAngularFolder, demo }, { key: "nd.demo.angular.run.watch.android", - value: "npm run nd.open.android.studio && npm run nd.build.run.demo.angular.app.android", + value: "npm run nd.open.android.studio && npm run nd.demo.angular.tns.run.android", shortCommands: ["demo-angular android simulator attach & watch", "demo-angular android device attach & watch"], + buildCommand: "npm run nd.build.native.android", patterns: [ androidSourcePath ], @@ -231,8 +190,9 @@ function getPluginPreDefinedScripts(srcPath, demoFolder, demoAngularFolder, demo }, { key: "nd.demo.angular.run.watch.ios", - value: "npm run nd.open.xcode && npm run nd.build.run.simulator.demo.angular.app.ios", + value: "npm run nd.open.xcode && npm run npm run nd.demo.angular.tns.run.ios", shortCommands: ["demo-angular ios simulator attach & watch"], + buildCommand: "npm run nd.build.simulator.native.ios", patterns: [ iosSourcePath ], @@ -240,8 +200,9 @@ function getPluginPreDefinedScripts(srcPath, demoFolder, demoAngularFolder, demo }, { key: "nd.demo.angular.run.watch.device.ios", - value: "npm run nd.open.xcode && npm run nd.build.run.demo.angular.app.ios", + value: "npm run nd.open.xcode && npm run nd.demo.angular.tns.run.ios", shortCommands: ["demo-angular ios device attach & watch"], + buildCommand: "npm run nd.build.device.native.ios", patterns: [ iosSourcePath ], @@ -249,8 +210,9 @@ function getPluginPreDefinedScripts(srcPath, demoFolder, demoAngularFolder, demo }, { key: "nd.demo.vue.run.watch.android", - value: "npm run nd.open.android.studio && npm run nd.build.run.demo.vue.app.android", + value: "npm run nd.open.android.studio && npm run nd.demo.vue.tns.run.android", shortCommands: ["demo-vue android simulator attach & watch", "demo-vue android device attach & watch"], + buildCommand: "npm run nd.build.native.android", patterns: [ androidSourcePath ], @@ -261,8 +223,9 @@ function getPluginPreDefinedScripts(srcPath, demoFolder, demoAngularFolder, demo }, { key: "nd.demo.vue.run.watch.ios", - value: "npm run nd.open.xcode && npm run nd.build.run.simulator.demo.vue.app.ios", + value: "npm run nd.open.xcode && npm run npm run nd.demo.vue.tns.run.ios", shortCommands: ["demo-vue ios simulator attach & watch"], + buildCommand: "npm run nd.build.simulator.native.ios", patterns: [ iosSourcePath ], @@ -270,8 +233,9 @@ function getPluginPreDefinedScripts(srcPath, demoFolder, demoAngularFolder, demo }, { key: "nd.demo.vue.run.watch.device.ios", - value: "npm run nd.open.xcode && npm run nd.build.run.demo.vue.app.ios", + value: "npm run nd.open.xcode && npm run nd.demo.vue.tns.run.ios", shortCommands: ["demo-vue ios device attach & watch"], + buildCommand: "npm run nd.build.device.native.ios", patterns: [ iosSourcePath ], @@ -285,7 +249,7 @@ function getPluginPreDefinedScripts(srcPath, demoFolder, demoAngularFolder, demo }, { key: "nd.demo.tns.run.ios", - value: "cd " + demoFolder + " && tns build ios && tns run ios --syncAllFiles" + provisioningParam, + value: "cd " + demoFolder + " && tns run ios --syncAllFiles" + provisioningParam, description: "Runs the 'demo' app on iOS with '--syncAllFiles' argument", category: "secondary" }, @@ -297,7 +261,7 @@ function getPluginPreDefinedScripts(srcPath, demoFolder, demoAngularFolder, demo }, { key: "nd.demo.angular.tns.run.ios", - value: "cd " + demoAngularFolder + " && tns build ios && tns run ios --syncAllFiles" + provisioningParam, + value: "cd " + demoAngularFolder + " && tns run ios --syncAllFiles" + provisioningParam, description: "Runs the 'demo-angular' app on iOS with '--syncAllFiles' argument", category: "secondary" }, @@ -309,7 +273,7 @@ function getPluginPreDefinedScripts(srcPath, demoFolder, demoAngularFolder, demo }, { key: "nd.demo.vue.tns.run.ios", - value: "cd " + demoVueFolder + " && tns build ios && tns run ios --syncAllFiles" + provisioningParam, + value: "cd " + demoVueFolder + " && tns run ios --syncAllFiles" + provisioningParam, description: "Runs the 'demo-vue' app on iOS with '--syncAllFiles' argument", category: "secondary" }, diff --git a/src/scripts/run.js b/src/scripts/run.js index 159d181..071e658 100644 --- a/src/scripts/run.js +++ b/src/scripts/run.js @@ -14,6 +14,7 @@ let jsonFile = fs.readFileSync(__dirname + "/nd-package.json"); var jsonObject = JSON.parse(jsonFile); const shortCommands = jsonHelper.getShortCommandsDictionary(jsonObject); const watchers = jsonHelper.getWatchersDictionary(jsonObject); +const buildCommands = jsonHelper.getBuildCommandsDictionary(jsonObject); const inputDemoKey = "demo"; const inputPlatformKey = "platform"; @@ -26,10 +27,14 @@ const targetTypes = ["simulator", "device"]; const actionTypes = ["attach", "attach & watch"]; logger.setIsEnabled(process.argv[2] == "log" ? true : false); -let shouldStartNew = false; -let runChildProcess; -let processKilled = false; -let startingProcess = false; +let shouldStartNewBuildProcess = false; +let initialBuildProcess; +let mainChildProcess; +let buildChildProcess; +let initialBuildProcessKilled = true; +let mainProcessKilled = true; +let buildProcessKilled = true; +let buildProcessStarting = false; let processTimeout; let watcherTimeout; @@ -57,6 +62,14 @@ function getWatcherPair(key) { }); } +function getBuildCommandPair(key) { + return buildCommands.find(function (element) { + var found; + found = element.key == key; + return found; + }); +} + function initPrompter() { const questions = [ { @@ -102,7 +115,10 @@ function initPrompter() { const command = parseInput(inputParams); const watcher = getWatcherDetails(inputParams); - execute(command, watcher); + const buildCommand = getBuildCommand(inputParams); + console.log(chalk.blue("'nativescript-dev-debugging': Starting: ") + chalk.yellow(command)); + + executeInitialBuild(command, watcher, buildCommand); }); } @@ -149,6 +165,20 @@ function getWatcherDetails(inputParams) { return undefined; } +function getBuildCommand(inputParams) { + logger.logObject("get build command for:", inputParams); + const inputCommand = formatInput(inputParams); + var ndCommandPair = getShortCommandPair(inputCommand); + var buildCommandPair = getBuildCommandPair(ndCommandPair.key); + if (buildCommandPair) { + return buildCommandPair.value; + } + + logger.logObject("No build command found for for:", inputParams); + + return undefined; +} + let acceptedFileExtensions = []; function buildWildcardList(path) { @@ -160,11 +190,20 @@ function buildWildcardList(path) { return result.length > 0 ? result : undefined; } -function execute(command, watcher) { - console.log(chalk.blue("'nativescript-dev-debugging': Starting: ") + chalk.yellow(command)); - startingProcess = true; +function executeInitialBuild(command, watcher, buildCommand) { + logger.logMessage("Starting 'executeInitialBuild' child process"); + initialBuildProcessKilled = false; + initialBuildProcess = spawn(buildCommand, [], { stdio: 'inherit', shell: true, detached: true }); + initialBuildProcess.on("close", function (code, signal) { + logger.logMessage("CHILD PROCESS CLOSED: for 'initialBuildProcess' with code: " + code + " and signal " + signal); + executeMainCommandWatcher(command, watcher, buildCommand); + initialBuildProcessKilled = true; + }); +} + +function executeMainCommandWatcher(command, watcher, buildCommand) { + logger.logMessage("CHILD PROCESS STARTED: 'executeMainCommandWatcher'") startProcess(command); - startingProcess = false; if (watcher && watcher.patterns) { // Glob to ignore .dotfiles @@ -197,10 +236,14 @@ function execute(command, watcher) { } watcherTimeout = setTimeout(() => { - if (!processKilled) { - shouldStartNew = true; - - killChildProcess(); + if (!buildProcessKilled) { + shouldStartNewBuildProcess = true; + killBuildChildProcess(); + } else { + shouldStartNewBuildProcess = false; + buildProcessStarting = true; + startProcessForWatcher(buildCommand); + buildProcessStarting = false; } }, 2000); } @@ -209,36 +252,66 @@ function execute(command, watcher) { } function startProcess(command) { - if (startingProcess) { - logger.logMessage("Starting child process") - runChildProcess = spawn(command, [], { stdio: 'inherit', shell: true, detached: true }); - processKilled = false; - runChildProcess.on("close", function (code, signal) { - logger.logMessage("'nd.run' child process 'close' with code: " + code + " and signal " + signal); - if (shouldStartNew) { + mainProcessKilled = false; + mainChildProcess = spawn(command, [], { stdio: 'inherit', shell: true, detached: true }); + mainChildProcess.on("close", function (code, signal) { + logger.logMessage("CHILD PROCESS CLOSED: for 'mainChildProcess' with code: " + code + " and signal " + signal); + mainProcessKilled = true; + }); +} + +function startProcessForWatcher(command) { + if (buildProcessStarting) { + logger.logMessage("CHILD PROCESS STARTED: for build with script: " + command) + buildProcessKilled = false; + buildChildProcess = spawn(command, [], { stdio: 'inherit', shell: true, detached: true }); + buildChildProcess.on("close", function (code, signal) { + logger.logMessage("CHILD PROCESS CLOSED: for 'buildChildProcess' with code: " + code + " and signal " + signal); + if (shouldStartNewBuildProcess) { shouldStartNew = false; if (processTimeout) { clearTimeout(processTimeout); } processTimeout = setTimeout(() => { - startingProcess = true; - startProcess(command); - startingProcess = false; + shouldStartNewBuildProcess = false; + buildProcessStarting = true; + startProcessForWatcher(command); + buildProcessStarting = false; }, 1500); } - processKilled = true; + buildProcessKilled = true; }); } } -function killChildProcess() { - logger.logMessage("Kill child process " + runChildProcess.pid); +function killInitialBuildChildProcess() { + if (!initialBuildProcessKilled && initialBuildProcess) { + logger.logMessage("Kill initial build child process " + initialBuildProcess.pid); - // Starts new child_process by closing the previous one - killProcessTree(runChildProcess.pid); - process.kill(-runChildProcess.pid); + killProcessTree(initialBuildProcess.pid); + process.kill(-initialBuildProcess.pid); + } +} + +function killBuildChildProcess() { + if (!buildProcessKilled && buildChildProcess) { + logger.logMessage("Kill build child process " + buildChildProcess.pid); + + killProcessTree(buildChildProcess.pid); + process.kill(-buildChildProcess.pid); + } +} + +function killMainChildProcess() { + if (!mainProcessKilled && mainChildProcess) { + logger.logMessage("Kill main child process " + mainChildProcess.pid); + + // Starts new child_process by closing the previous one + killProcessTree(mainChildProcess.pid); + process.kill(-mainChildProcess.pid); + } } function killProcessTree(pid) { @@ -260,9 +333,9 @@ function execAsUser(cmd) { process.on('SIGINT', function () { logger.logMessage("Stopping 'nativescript-dev-debugging") - if (!processKilled) { - killChildProcess(); - } + killMainChildProcess(); + killBuildChildProcess(); + killInitialBuildChildProcess(); process.exit(); }); \ No newline at end of file