-
Notifications
You must be signed in to change notification settings - Fork 145
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #256 from BranchMetrics/fix_before_hook
Fix before hook
- Loading branch information
Showing
5 changed files
with
155 additions
and
269 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,154 +1,97 @@ | ||
/** | ||
Hook is executed when plugin is added to the project. | ||
It will check all necessary module dependencies and install the missing ones locally. | ||
*/ | ||
|
||
var exec = require('child_process').exec, | ||
path = require('path'), | ||
fs = require('fs'), | ||
INSTALLATION_FLAG_FILE_NAME = '.installed'; | ||
|
||
// region NPM specific | ||
|
||
/** | ||
* Check if node package is installed. | ||
* | ||
* @param {String} moduleName | ||
* @return {Boolean} true if package already installed | ||
*/ | ||
function isNodeModuleInstalled(moduleName) { | ||
var installed = true; | ||
try { | ||
var module = require(moduleName); | ||
} catch (err) { | ||
installed = false; | ||
'use strict'; | ||
|
||
// installs the node modules via npm install one at a time | ||
// @return {callback(error)} | ||
function installNodeModules(exec, modules, callback) { | ||
// base case | ||
if (modules.length <= 0) { | ||
return callback(false); | ||
} | ||
|
||
return installed; | ||
} | ||
|
||
/** | ||
* Install node module locally. | ||
* Basically, it runs 'npm install module_name'. | ||
* | ||
* @param {String} moduleName | ||
* @param {Callback(error)} callback | ||
*/ | ||
function installNodeModule(moduleName, callback) { | ||
if (isNodeModuleInstalled(moduleName)) { | ||
printLog('Node module ' + moduleName + ' is found'); | ||
callback(null); | ||
return; | ||
} | ||
printLog('Can\'t find module ' + moduleName + ', running npm install'); | ||
|
||
var cmd = 'cd plugins/io.branch.sdk && npm install -D ' + moduleName; | ||
exec(cmd, function(err, stdout, stderr) { | ||
callback(err); | ||
}); | ||
} | ||
|
||
/** | ||
* Install all required node packages. | ||
*/ | ||
function installRequiredNodeModules(modulesToInstall) { | ||
if (!modulesToInstall.length) { | ||
return; | ||
} | ||
// install one at a time | ||
var module = modules.pop(); | ||
console.log('Installing "' + module + '"'); | ||
|
||
var moduleName = modulesToInstall.shift(); | ||
installNodeModule(moduleName, function(err) { | ||
var install = 'npm install --prefix ./plugins/io.branch.sdk -D ' + module; | ||
exec(install, function(err, stdout, stderr) { | ||
// handle error | ||
if (err) { | ||
printLog('Failed to install module ' + moduleName + ':' + err); | ||
return; | ||
console.error('Failed to install Branch Dependency: "' + module + '"'); | ||
return callback(true); | ||
} | ||
// next module | ||
else { | ||
installNodeModules(exec, modules, callback); | ||
} | ||
|
||
printLog('Module ' + moduleName + ' is installed'); | ||
installRequiredNodeModules(modulesToInstall); | ||
}); | ||
} | ||
|
||
// endregion | ||
|
||
// region Logging | ||
|
||
function logStart() { | ||
console.log('Checking dependencies:'); | ||
} | ||
|
||
function printLog(msg) { | ||
var formattedMsg = ' ' + msg; | ||
console.log(formattedMsg); | ||
// checks to see which node modules need to be installed | ||
// @return {[string]} of node modules from package.json.dependencies | ||
function getNodeModulesToInstall(dependencies) { | ||
var modules = []; | ||
for (var module in dependencies) { | ||
if (dependencies.hasOwnProperty(module)) { | ||
try { | ||
var exists = require(module); | ||
} catch (err) { | ||
modules.push(module); | ||
} | ||
} | ||
} | ||
return modules; | ||
} | ||
|
||
// endregion | ||
|
||
// region Private API | ||
|
||
/** | ||
* Check if we already executed this hook. | ||
* | ||
* @param {Object} ctx - cordova context | ||
* @return {Boolean} true if already executed; otherwise - false | ||
*/ | ||
function isInstallationAlreadyPerformed(ctx) { | ||
var pathToInstallFlag = path.join(ctx.opts.projectRoot, 'plugins', ctx.opts.plugin.id, INSTALLATION_FLAG_FILE_NAME), | ||
isInstalled = false; | ||
// if the Branch SDK package has already been installed | ||
// @return {boolean} based on .installed file is found | ||
function getPackageInstalled(filesave, installFlagLocation) { | ||
try { | ||
var content = fs.readFileSync(pathToInstallFlag); | ||
isInstalled = true; | ||
var exists = filesave.readFileSync(installFlagLocation); | ||
return true; | ||
} catch (err) { | ||
return false; | ||
} | ||
|
||
return isInstalled; | ||
} | ||
|
||
/** | ||
* Create empty file - indicator, that we tried to install dependency modules after installation. | ||
* We have to do that, or this hook is gonna be called on any plugin installation. | ||
*/ | ||
function createPluginInstalledFlag(ctx) { | ||
var pathToInstallFlag = path.join(ctx.opts.projectRoot, 'plugins', ctx.opts.plugin.id, INSTALLATION_FLAG_FILE_NAME); | ||
|
||
fs.closeSync(fs.openSync(pathToInstallFlag, 'w')); | ||
} | ||
|
||
// endregion | ||
|
||
/** | ||
* Read dependencies from the package.json. | ||
* We will install them on the next step. | ||
* | ||
* @param {Object} ctx - cordova context | ||
* @return {Array} list of modules to install | ||
*/ | ||
function readDependenciesFromPackageJson(ctx) { | ||
var data = require(path.join(ctx.opts.projectRoot, 'plugins', ctx.opts.plugin.id, 'package.json')), | ||
dependencies = data['dependencies'], | ||
modules = []; | ||
|
||
if (!dependencies) { | ||
return modules; | ||
} | ||
|
||
for (var module in dependencies) { | ||
modules.push(module); | ||
} | ||
|
||
return modules; | ||
// set that the Branch SDK package has been installed | ||
// @return {void} based on .installed file is created | ||
function setPackageInstalled(filesave, installFlagLocation) { | ||
filesave.closeSync(filesave.openSync(installFlagLocation, 'w')); | ||
} | ||
|
||
// hook's entry point | ||
module.exports = function(ctx) { | ||
// exit if we already executed this hook once | ||
if (isInstallationAlreadyPerformed(ctx)) { | ||
// hooks entry point | ||
// @return {void} based on async npm install completion | ||
module.exports = function(context) { | ||
// properties | ||
var q = context.requireCordovaModule('q'); | ||
var async = new q.defer(); | ||
var filesave = require('fs'); | ||
var path = require('path'); | ||
var exec = require('child_process').exec; | ||
var installFlagName = '.installed'; | ||
var installFlagLocation = path.join(context.opts.projectRoot, 'plugins', context.opts.plugin.id, installFlagName); | ||
var dependencies = require(path.join(context.opts.projectRoot, 'plugins', context.opts.plugin.id, 'package.json')).dependencies; | ||
|
||
// only run once | ||
if (getPackageInstalled(filesave, installFlagLocation)) { | ||
return; | ||
} | ||
|
||
logStart(); | ||
|
||
var modules = readDependenciesFromPackageJson(ctx); | ||
installRequiredNodeModules(modules); | ||
// install node modules | ||
var modules = getNodeModulesToInstall(dependencies); | ||
installNodeModules(exec, modules, function(err) { | ||
// handle error | ||
if (err) { | ||
console.error('Failed to install the Branch SDK'); | ||
} | ||
// only run once | ||
else { | ||
setPackageInstalled(filesave, installFlagLocation); | ||
} | ||
// async complete | ||
async.resolve(); | ||
}); | ||
|
||
createPluginInstalledFlag(ctx); | ||
// wait until callbacks from the all the npm install complete | ||
return async.promise; | ||
}; |
Oops, something went wrong.