[Service] Integrate DeviceHome and SignalingServer
[platform/framework/web/wrtjs.git] / device_home / node_modules / jake / lib / program.js
1 /*
2  * Jake JavaScript build tool
3  * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17 */
18
19 let fs = require('fs');
20 let parseargs = require('./parseargs');
21 let utils = require('./utils');
22 let Program;
23 let usage = require('fs').readFileSync(`${__dirname}/../usage.txt`).toString();
24 let { Task } = require('./task/task');
25
26 function die(msg) {
27   console.log(msg);
28   process.stdout.write('', function () {
29     process.stderr.write('', function () {
30       process.exit();
31     });
32   });
33 }
34
35 let preempts = {
36   version: function () {
37     die(jake.version);
38   },
39   help: function () {
40     die(usage);
41   }
42 };
43
44 let AVAILABLE_OPTS = [
45   { full: 'jakefile',
46     abbr: 'f',
47     expectValue: true
48   },
49   { full: 'quiet',
50     abbr: 'q',
51     expectValue: false
52   },
53   { full: 'directory',
54     abbr: 'C',
55     expectValue: true
56   },
57   { full: 'always-make',
58     abbr: 'B',
59     expectValue: false
60   },
61   { full: 'tasks',
62     abbr: 'T',
63     expectValue: false,
64     allowValue: true
65   },
66   // Alias t
67   { full: 'tasks',
68     abbr: 't',
69     expectValue: false,
70     allowValue: true
71   },
72   // Alias ls
73   { full: 'tasks',
74     abbr: 'ls',
75     expectValue: false,
76     allowValue: true
77   },
78   { full: 'help',
79     abbr: 'h',
80   },
81   { full: 'version',
82     abbr: 'V',
83   },
84   // Alias lowercase v
85   { full: 'version',
86     abbr: 'v',
87   },
88   { full: 'jakelibdir',
89     abbr: 'J',
90     expectValue: true
91   },
92   { full: 'allow-rejection',
93     abbr: 'ar',
94     expectValue: false
95   }
96 ];
97
98 Program = function () {
99   this.availableOpts = AVAILABLE_OPTS;
100   this.opts = {};
101   this.taskNames = null;
102   this.taskArgs = null;
103   this.envVars = null;
104   this.die = die;
105 };
106
107 Program.prototype = new (function () {
108
109   this.handleErr = function (err) {
110     if (jake.listeners('error').length !== 0) {
111       jake.emit('error', err);
112       return;
113     }
114
115     if (jake.listeners('error').length) {
116       jake.emit('error', err);
117       return;
118     }
119
120     utils.logger.error('jake aborted.');
121     if (err.stack) {
122       utils.logger.error(err.stack);
123     }
124     else {
125       utils.logger.error(err.message);
126     }
127
128     process.stdout.write('', function () {
129       process.stderr.write('', function () {
130         jake.errorCode = jake.errorCode || 1;
131         process.exit(jake.errorCode);
132       });
133     });
134   };
135
136   this.parseArgs = function (args) {
137     let result = (new parseargs.Parser(this.availableOpts)).parse(args);
138     this.setOpts(result.opts);
139     this.setTaskNames(result.taskNames);
140     this.setEnvVars(result.envVars);
141   };
142
143   this.setOpts = function (options) {
144     let opts = options || {};
145     Object.assign(this.opts, opts);
146   };
147
148   this.internalOpts = function (options) {
149     this.availableOpts = this.availableOpts.concat(options);
150   };
151
152   this.autocompletions = function (cur) {
153     let p; let i; let task;
154     let commonPrefix = '';
155     let matches = [];
156
157     for (p in jake.Task) {
158       task = jake.Task[p];
159       if (
160         'fullName' in task
161           && (
162             // if empty string, program converts to true
163             cur === true ||
164             task.fullName.indexOf(cur) === 0
165           )
166       ) {
167         if (matches.length === 0) {
168           commonPrefix = task.fullName;
169         }
170         else {
171           for (i = commonPrefix.length; i > -1; --i) {
172             commonPrefix = commonPrefix.substr(0, i);
173             if (task.fullName.indexOf(commonPrefix) === 0) {
174               break;
175             }
176           }
177         }
178         matches.push(task.fullName);
179       }
180     }
181
182     if (matches.length > 1 && commonPrefix === cur) {
183       matches.unshift('yes-space');
184     }
185     else {
186       matches.unshift('no-space');
187     }
188
189     process.stdout.write(matches.join(' '));
190   };
191
192   this.setTaskNames = function (names) {
193     if (names && !Array.isArray(names)) {
194       throw new Error('Task names must be an array');
195     }
196     this.taskNames = (names && names.length) ? names : ['default'];
197   };
198
199   this.setEnvVars = function (vars) {
200     this.envVars = vars || null;
201   };
202
203   this.firstPreemptiveOption = function () {
204     let opts = this.opts;
205     for (let p in opts) {
206       if (preempts[p]) {
207         return preempts[p];
208       }
209     }
210     return false;
211   };
212
213   this.init = function (configuration) {
214     let self = this;
215     let config = configuration || {};
216     if (config.options) {
217       this.setOpts(config.options);
218     }
219     if (config.taskNames) {
220       this.setTaskNames(config.taskNames);
221     }
222     if (config.envVars) {
223       this.setEnvVars(config.envVars);
224     }
225     process.addListener('uncaughtException', function (err) {
226       self.handleErr(err);
227     });
228     if (!this.opts['allow-rejection']) {
229       process.addListener('unhandledRejection', (reason, promise) => {
230         utils.logger.error('Unhandled rejection at:', promise, 'reason:', reason);
231         self.handleErr(reason);
232       });
233     }
234     if (this.envVars) {
235       Object.assign(process.env, this.envVars);
236     }
237   };
238
239   this.run = function () {
240     let rootTask;
241     let taskNames;
242     let dirname;
243     let opts = this.opts;
244
245     if (opts.autocomplete) {
246       return this.autocompletions(opts['autocomplete-cur'], opts['autocomplete-prev']);
247     }
248     // Run with `jake -T`, just show descriptions
249     if (opts.tasks) {
250       return jake.showAllTaskDescriptions(opts.tasks);
251     }
252
253     taskNames = this.taskNames;
254     if (!(Array.isArray(taskNames) && taskNames.length)) {
255       throw new Error('Please pass jake.runTasks an array of task-names');
256     }
257
258     // Set working dir
259     dirname = opts.directory;
260     if (dirname) {
261       if (fs.existsSync(dirname) &&
262         fs.statSync(dirname).isDirectory()) {
263         process.chdir(dirname);
264       }
265       else {
266         throw new Error(dirname + ' is not a valid directory path');
267       }
268     }
269
270     rootTask = task(Task.ROOT_TASK_NAME, taskNames, function () {});
271     rootTask._internal = true;
272
273     rootTask.once('complete', function () {
274       jake.emit('complete');
275     });
276     jake.emit('start');
277     rootTask.invoke();
278   };
279
280 })();
281
282 module.exports.Program = Program;