|
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