|
1 | | -/** |
2 | | -Hook is executed when plugin is added to the project. |
3 | | -It will check all necessary module dependencies and install the missing ones locally. |
4 | | -*/ |
5 | | - |
6 | | -var exec = require('child_process').exec, |
7 | | - path = require('path'), |
8 | | - fs = require('fs'), |
9 | | - INSTALLATION_FLAG_FILE_NAME = '.installed'; |
10 | | - |
11 | | -// region NPM specific |
12 | | - |
13 | | -/** |
14 | | - * Check if node package is installed. |
15 | | - * |
16 | | - * @param {String} moduleName |
17 | | - * @return {Boolean} true if package already installed |
18 | | - */ |
19 | | -function isNodeModuleInstalled(moduleName) { |
20 | | - var installed = true; |
21 | | - try { |
22 | | - var module = require(moduleName); |
23 | | - } catch (err) { |
24 | | - installed = false; |
| 1 | +'use strict'; |
| 2 | + |
| 3 | +// installs the node modules via npm install one at a time |
| 4 | +// @return {callback(error)} |
| 5 | +function installNodeModules(exec, modules, callback) { |
| 6 | + // base case |
| 7 | + if (modules.length <= 0) { |
| 8 | + return callback(false); |
25 | 9 | } |
26 | 10 |
|
27 | | - return installed; |
28 | | -} |
29 | | - |
30 | | -/** |
31 | | - * Install node module locally. |
32 | | - * Basically, it runs 'npm install module_name'. |
33 | | - * |
34 | | - * @param {String} moduleName |
35 | | - * @param {Callback(error)} callback |
36 | | - */ |
37 | | -function installNodeModule(moduleName, callback) { |
38 | | - if (isNodeModuleInstalled(moduleName)) { |
39 | | - printLog('Node module ' + moduleName + ' is found'); |
40 | | - callback(null); |
41 | | - return; |
42 | | - } |
43 | | - printLog('Can\'t find module ' + moduleName + ', running npm install'); |
44 | | - |
45 | | - var cmd = 'cd plugins/io.branch.sdk && npm install -D ' + moduleName; |
46 | | - exec(cmd, function(err, stdout, stderr) { |
47 | | - callback(err); |
48 | | - }); |
49 | | -} |
50 | | - |
51 | | -/** |
52 | | - * Install all required node packages. |
53 | | - */ |
54 | | -function installRequiredNodeModules(modulesToInstall) { |
55 | | - if (!modulesToInstall.length) { |
56 | | - return; |
57 | | - } |
| 11 | + // install one at a time |
| 12 | + var module = modules.pop(); |
| 13 | + console.log('Installing "' + module + '"'); |
58 | 14 |
|
59 | | - var moduleName = modulesToInstall.shift(); |
60 | | - installNodeModule(moduleName, function(err) { |
| 15 | + var install = 'npm install --prefix ./plugins/io.branch.sdk -D ' + module; |
| 16 | + exec(install, function(err, stdout, stderr) { |
| 17 | + // handle error |
61 | 18 | if (err) { |
62 | | - printLog('Failed to install module ' + moduleName + ':' + err); |
63 | | - return; |
| 19 | + console.error('Failed to install Branch Dependency: "' + module + '"'); |
| 20 | + return callback(true); |
| 21 | + } |
| 22 | + // next module |
| 23 | + else { |
| 24 | + installNodeModules(exec, modules, callback); |
64 | 25 | } |
65 | | - |
66 | | - printLog('Module ' + moduleName + ' is installed'); |
67 | | - installRequiredNodeModules(modulesToInstall); |
68 | 26 | }); |
69 | 27 | } |
70 | 28 |
|
71 | | -// endregion |
72 | | - |
73 | | -// region Logging |
74 | | - |
75 | | -function logStart() { |
76 | | - console.log('Checking dependencies:'); |
77 | | -} |
78 | | - |
79 | | -function printLog(msg) { |
80 | | - var formattedMsg = ' ' + msg; |
81 | | - console.log(formattedMsg); |
| 29 | +// checks to see which node modules need to be installed |
| 30 | +// @return {[string]} of node modules from package.json.dependencies |
| 31 | +function getNodeModulesToInstall(dependencies) { |
| 32 | + var modules = []; |
| 33 | + for (var module in dependencies) { |
| 34 | + if (dependencies.hasOwnProperty(module)) { |
| 35 | + try { |
| 36 | + var exists = require(module); |
| 37 | + } catch (err) { |
| 38 | + modules.push(module); |
| 39 | + } |
| 40 | + } |
| 41 | + } |
| 42 | + return modules; |
82 | 43 | } |
83 | 44 |
|
84 | | -// endregion |
85 | | - |
86 | | -// region Private API |
87 | | - |
88 | | -/** |
89 | | - * Check if we already executed this hook. |
90 | | - * |
91 | | - * @param {Object} ctx - cordova context |
92 | | - * @return {Boolean} true if already executed; otherwise - false |
93 | | - */ |
94 | | -function isInstallationAlreadyPerformed(ctx) { |
95 | | - var pathToInstallFlag = path.join(ctx.opts.projectRoot, 'plugins', ctx.opts.plugin.id, INSTALLATION_FLAG_FILE_NAME), |
96 | | - isInstalled = false; |
| 45 | +// if the Branch SDK package has already been installed |
| 46 | +// @return {boolean} based on .installed file is found |
| 47 | +function getPackageInstalled(filesave, installFlagLocation) { |
97 | 48 | try { |
98 | | - var content = fs.readFileSync(pathToInstallFlag); |
99 | | - isInstalled = true; |
| 49 | + var exists = filesave.readFileSync(installFlagLocation); |
| 50 | + return true; |
100 | 51 | } catch (err) { |
| 52 | + return false; |
101 | 53 | } |
102 | | - |
103 | | - return isInstalled; |
104 | 54 | } |
105 | 55 |
|
106 | | -/** |
107 | | - * Create empty file - indicator, that we tried to install dependency modules after installation. |
108 | | - * We have to do that, or this hook is gonna be called on any plugin installation. |
109 | | - */ |
110 | | -function createPluginInstalledFlag(ctx) { |
111 | | - var pathToInstallFlag = path.join(ctx.opts.projectRoot, 'plugins', ctx.opts.plugin.id, INSTALLATION_FLAG_FILE_NAME); |
112 | | - |
113 | | - fs.closeSync(fs.openSync(pathToInstallFlag, 'w')); |
114 | | -} |
115 | | - |
116 | | -// endregion |
117 | | - |
118 | | -/** |
119 | | - * Read dependencies from the package.json. |
120 | | - * We will install them on the next step. |
121 | | - * |
122 | | - * @param {Object} ctx - cordova context |
123 | | - * @return {Array} list of modules to install |
124 | | - */ |
125 | | -function readDependenciesFromPackageJson(ctx) { |
126 | | - var data = require(path.join(ctx.opts.projectRoot, 'plugins', ctx.opts.plugin.id, 'package.json')), |
127 | | - dependencies = data['dependencies'], |
128 | | - modules = []; |
129 | | - |
130 | | - if (!dependencies) { |
131 | | - return modules; |
132 | | - } |
133 | | - |
134 | | - for (var module in dependencies) { |
135 | | - modules.push(module); |
136 | | - } |
137 | | - |
138 | | - return modules; |
| 56 | +// set that the Branch SDK package has been installed |
| 57 | +// @return {void} based on .installed file is created |
| 58 | +function setPackageInstalled(filesave, installFlagLocation) { |
| 59 | + filesave.closeSync(filesave.openSync(installFlagLocation, 'w')); |
139 | 60 | } |
140 | 61 |
|
141 | | -// hook's entry point |
142 | | -module.exports = function(ctx) { |
143 | | - // exit if we already executed this hook once |
144 | | - if (isInstallationAlreadyPerformed(ctx)) { |
| 62 | +// hooks entry point |
| 63 | +// @return {void} based on async npm install completion |
| 64 | +module.exports = function(context) { |
| 65 | + // properties |
| 66 | + var q = context.requireCordovaModule('q'); |
| 67 | + var async = new q.defer(); |
| 68 | + var filesave = require('fs'); |
| 69 | + var path = require('path'); |
| 70 | + var exec = require('child_process').exec; |
| 71 | + var installFlagName = '.installed'; |
| 72 | + var installFlagLocation = path.join(context.opts.projectRoot, 'plugins', context.opts.plugin.id, installFlagName); |
| 73 | + var dependencies = require(path.join(context.opts.projectRoot, 'plugins', context.opts.plugin.id, 'package.json')).dependencies; |
| 74 | + |
| 75 | + // only run once |
| 76 | + if (getPackageInstalled(filesave, installFlagLocation)) { |
145 | 77 | return; |
146 | 78 | } |
147 | 79 |
|
148 | | - logStart(); |
149 | | - |
150 | | - var modules = readDependenciesFromPackageJson(ctx); |
151 | | - installRequiredNodeModules(modules); |
| 80 | + // install node modules |
| 81 | + var modules = getNodeModulesToInstall(dependencies); |
| 82 | + installNodeModules(exec, modules, function(err) { |
| 83 | + // handle error |
| 84 | + if (err) { |
| 85 | + console.error('Failed to install the Branch SDK'); |
| 86 | + } |
| 87 | + // only run once |
| 88 | + else { |
| 89 | + setPackageInstalled(filesave, installFlagLocation); |
| 90 | + } |
| 91 | + // async complete |
| 92 | + async.resolve(); |
| 93 | + }); |
152 | 94 |
|
153 | | - createPluginInstalledFlag(ctx); |
| 95 | + // wait until callbacks from the all the npm install complete |
| 96 | + return async.promise; |
154 | 97 | }; |
0 commit comments