Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / node-pre-gyp / lib / util / napi.js
1 "use strict";
2
3 var fs = require('fs');
4
5 module.exports = exports;
6
7 var versionArray = process.version
8         .substr(1)
9         .replace(/-.*$/, '')
10         .split('.')
11         .map(function(item) {
12                 return +item;
13         });
14
15 var napi_multiple_commands = [
16         'build',
17         'clean',
18         'configure',
19         'package',
20         'publish',
21         'reveal',
22         'testbinary',
23         'testpackage',
24         'unpublish'
25 ];
26
27 var napi_build_version_tag = 'napi_build_version=';
28
29 module.exports.get_napi_version = function(target) { // target may be undefined
30         // returns the non-zero numeric napi version or undefined if napi is not supported.
31         // correctly supporting target requires an updated cross-walk
32         var version = process.versions.napi; // can be undefined
33         if (!version) { // this code should never need to be updated
34                 if (versionArray[0] === 9 && versionArray[1] >= 3) version = 2; // 9.3.0+
35                 else if (versionArray[0] === 8) version = 1; // 8.0.0+
36         }
37         return version;
38 };
39
40 module.exports.get_napi_version_as_string = function(target) {
41         // returns the napi version as a string or an empty string if napi is not supported.
42         var version = module.exports.get_napi_version(target);
43         return version ? ''+version : '';
44 };
45
46 module.exports.validate_package_json = function(package_json, opts) { // throws Error
47
48         var binary = package_json.binary;
49         var module_path_ok = pathOK(binary.module_path);
50         var remote_path_ok = pathOK(binary.remote_path);
51         var package_name_ok = pathOK(binary.package_name);
52         var napi_build_versions = module.exports.get_napi_build_versions(package_json,opts,true);
53         var napi_build_versions_raw = module.exports.get_napi_build_versions_raw(package_json);
54
55         if (napi_build_versions) {
56                 napi_build_versions.forEach(function(napi_build_version){
57                         if (!(parseInt(napi_build_version,10) === napi_build_version && napi_build_version > 0)) {
58                                 throw new Error("All values specified in napi_versions must be positive integers.");
59                         }
60                 });
61         }
62
63         if (napi_build_versions && (!module_path_ok || (!remote_path_ok && !package_name_ok))) {
64                 throw new Error("When napi_versions is specified; module_path and either remote_path or " +
65                         "package_name must contain the substitution string '{napi_build_version}`.");
66         }
67
68         if ((module_path_ok || remote_path_ok || package_name_ok) && !napi_build_versions_raw) {
69                 throw new Error("When the substitution string '{napi_build_version}` is specified in " +
70                         "module_path, remote_path, or package_name; napi_versions must also be specified.");
71         }
72
73         if (napi_build_versions && !module.exports.get_best_napi_build_version(package_json, opts) && 
74         module.exports.build_napi_only(package_json)) {
75                 throw new Error(
76                         'The N-API version of this Node instance is ' + module.exports.get_napi_version(opts ? opts.target : undefined) + '. ' +
77                         'This module supports N-API version(s) ' + module.exports.get_napi_build_versions_raw(package_json) + '. ' +
78                         'This Node instance cannot run this module.');
79         }
80
81         if (napi_build_versions_raw && !napi_build_versions && module.exports.build_napi_only(package_json)) {
82                 throw new Error(
83                         'The N-API version of this Node instance is ' + module.exports.get_napi_version(opts ? opts.target : undefined) + '. ' +
84                         'This module supports N-API version(s) ' + module.exports.get_napi_build_versions_raw(package_json) + '. ' +
85                         'This Node instance cannot run this module.');
86         }
87
88 };
89
90 function pathOK (path) {
91         return path && (path.indexOf('{napi_build_version}') !== -1 || path.indexOf('{node_napi_label}') !== -1);
92 }
93
94 module.exports.expand_commands = function(package_json, opts, commands) {
95         var expanded_commands = [];
96         var napi_build_versions = module.exports.get_napi_build_versions(package_json, opts);
97         commands.forEach(function(command){
98                 if (napi_build_versions && command.name === 'install') {
99                         var napi_build_version = module.exports.get_best_napi_build_version(package_json, opts);
100                         var args = napi_build_version ? [ napi_build_version_tag+napi_build_version ] : [ ];
101                         expanded_commands.push ({ name: command.name, args: args });
102                 } else if (napi_build_versions && napi_multiple_commands.indexOf(command.name) !== -1) {
103                         napi_build_versions.forEach(function(napi_build_version){
104                                 var args = command.args.slice();
105                                 args.push (napi_build_version_tag+napi_build_version);
106                                 expanded_commands.push ({ name: command.name, args: args });
107                         });
108                 } else {
109                         expanded_commands.push (command);
110                 }
111         });
112         return expanded_commands;
113 };
114
115 module.exports.get_napi_build_versions = function(package_json, opts, warnings) { // opts may be undefined
116         var log = require('npmlog');
117         var napi_build_versions = [];
118         var supported_napi_version = module.exports.get_napi_version(opts ? opts.target : undefined);
119         // remove duplicates, verify each napi version can actaully be built
120         if (package_json.binary && package_json.binary.napi_versions) {
121                 package_json.binary.napi_versions.forEach(function(napi_version) {
122                         var duplicated = napi_build_versions.indexOf(napi_version) !== -1;
123                         if (!duplicated && supported_napi_version && napi_version <= supported_napi_version) {
124                                 napi_build_versions.push(napi_version);
125                         } else if (warnings && !duplicated && supported_napi_version) {
126                                 log.info('This Node instance does not support builds for N-API version', napi_version);
127                         }
128                 });
129         }
130         if (opts && opts["build-latest-napi-version-only"]) {
131                 var latest_version = 0;
132                 napi_build_versions.forEach(function(napi_version) {
133                         if (napi_version > latest_version) latest_version = napi_version;
134                 });
135                 napi_build_versions = latest_version ? [ latest_version ] : [];
136         }
137         return napi_build_versions.length ? napi_build_versions : undefined;
138 };
139
140 module.exports.get_napi_build_versions_raw = function(package_json) {
141         var napi_build_versions = [];
142         // remove duplicates
143         if (package_json.binary && package_json.binary.napi_versions) {
144                 package_json.binary.napi_versions.forEach(function(napi_version) {
145                         if (napi_build_versions.indexOf(napi_version) === -1) {
146                                 napi_build_versions.push(napi_version);
147                         }
148                 });
149         }
150         return napi_build_versions.length ? napi_build_versions : undefined;
151 };
152
153 module.exports.get_command_arg = function(napi_build_version) {
154         return napi_build_version_tag + napi_build_version;
155 };
156
157 module.exports.get_napi_build_version_from_command_args = function(command_args) {
158         for (var i = 0; i < command_args.length; i++) {
159                 var arg = command_args[i];
160                 if (arg.indexOf(napi_build_version_tag) === 0) {
161                         return parseInt(arg.substr(napi_build_version_tag.length),10);
162                 }
163         }
164         return undefined;
165 };
166
167 module.exports.swap_build_dir_out = function(napi_build_version) {
168         if (napi_build_version) {
169                 var rm = require('rimraf');
170                 rm.sync(module.exports.get_build_dir(napi_build_version));
171                 fs.renameSync('build', module.exports.get_build_dir(napi_build_version));
172         }
173 };
174
175 module.exports.swap_build_dir_in = function(napi_build_version) {
176         if (napi_build_version) {
177                 var rm = require('rimraf');
178                 rm.sync('build');
179                 fs.renameSync(module.exports.get_build_dir(napi_build_version), 'build');
180         }
181 };
182
183 module.exports.get_build_dir = function(napi_build_version) {
184         return 'build-tmp-napi-v'+napi_build_version;
185 };
186
187 module.exports.get_best_napi_build_version = function(package_json, opts) {
188         var best_napi_build_version = 0;
189         var napi_build_versions = module.exports.get_napi_build_versions (package_json, opts);
190         if (napi_build_versions) {
191                 var our_napi_version = module.exports.get_napi_version(opts ? opts.target : undefined);
192                 napi_build_versions.forEach(function(napi_build_version){
193                         if (napi_build_version > best_napi_build_version &&
194                                 napi_build_version <= our_napi_version) {
195                                 best_napi_build_version = napi_build_version;
196                         }
197                 });
198         }
199         return best_napi_build_version === 0 ? undefined : best_napi_build_version;
200 };
201
202 module.exports.build_napi_only = function(package_json) {
203         return package_json.binary && package_json.binary.package_name && 
204         package_json.binary.package_name.indexOf('{node_napi_label}') === -1;
205 };