[Service] Integrate DeviceHome and SignalingServer
[platform/framework/web/wrtjs.git] / device_home / node_modules / jake / lib / jake.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 if (!global.jake) {
20
21   let EventEmitter = require('events').EventEmitter;
22   // And so it begins
23   global.jake = new EventEmitter();
24
25   let fs = require('fs');
26   let chalk = require('chalk');
27   let taskNs = require('./task');
28   let Task = taskNs.Task;
29   let FileTask = taskNs.FileTask;
30   let DirectoryTask = taskNs.DirectoryTask;
31   let Rule = require('./rule').Rule;
32   let Namespace = require('./namespace').Namespace;
33   let RootNamespace = require('./namespace').RootNamespace;
34   let api = require('./api');
35   let utils = require('./utils');
36   let Program = require('./program').Program;
37   let loader = require('./loader')();
38   let pkg = JSON.parse(fs.readFileSync(__dirname + '/../package.json').toString());
39
40   const MAX_RULE_RECURSION_LEVEL = 16;
41
42   // Globalize jake and top-level API methods (e.g., `task`, `desc`)
43   Object.assign(global, api);
44
45   // Copy utils onto base jake
46   jake.logger = utils.logger;
47   jake.exec = utils.exec;
48
49   // File utils should be aliased directly on base jake as well
50   Object.assign(jake, utils.file);
51
52   // Also add top-level API methods to exported object for those who don't want to
53   // use the globals (`file` here will overwrite the 'file' utils namespace)
54   Object.assign(jake, api);
55
56   Object.assign(jake, new (function () {
57
58     this._invocationChain = [];
59     this._taskTimeout = 30000;
60
61     // Public properties
62     // =================
63     this.version = pkg.version;
64     // Used when Jake exits with a specific error-code
65     this.errorCode = null;
66     // Loads Jakefiles/jakelibdirs
67     this.loader = loader;
68     // The root of all ... namespaces
69     this.rootNamespace = new RootNamespace();
70     // Non-namespaced tasks are placed into the default
71     this.defaultNamespace = this.rootNamespace;
72     // Start in the default
73     this.currentNamespace = this.defaultNamespace;
74     // Saves the description created by a 'desc' call that prefaces a
75     // 'task' call that defines a task.
76     this.currentTaskDescription = null;
77     this.program = new Program();
78     this.FileList = require('filelist').FileList;
79     this.PackageTask = require('./package_task').PackageTask;
80     this.PublishTask = require('./publish_task').PublishTask;
81     this.TestTask = require('./test_task').TestTask;
82     this.Task = Task;
83     this.FileTask = FileTask;
84     this.DirectoryTask = DirectoryTask;
85     this.Namespace = Namespace;
86     this.Rule = Rule;
87
88     this.parseAllTasks = function () {
89       let _parseNs = function (ns) {
90         let nsTasks = ns.tasks;
91         let nsNamespaces = ns.childNamespaces;
92         for (let q in nsTasks) {
93           let nsTask = nsTasks[q];
94           jake.Task[nsTask.fullName] = nsTask;
95         }
96         for (let p in nsNamespaces) {
97           let nsNamespace = nsNamespaces[p];
98           _parseNs(nsNamespace);
99         }
100       };
101       _parseNs(jake.defaultNamespace);
102     };
103
104     /**
105      * Displays the list of descriptions avaliable for tasks defined in
106      * a Jakefile
107      */
108     this.showAllTaskDescriptions = function (f) {
109       let p;
110       let maxTaskNameLength = 0;
111       let task;
112       let padding;
113       let name;
114       let descr;
115       let filter = typeof f == 'string' ? f : null;
116
117       for (p in jake.Task) {
118         if (!Object.prototype.hasOwnProperty.call(jake.Task, p)) {
119           continue;
120         }
121         if (filter && p.indexOf(filter) == -1) {
122           continue;
123         }
124         task = jake.Task[p];
125         // Record the length of the longest task name -- used for
126         // pretty alignment of the task descriptions
127         if (task.description) {
128           maxTaskNameLength = p.length > maxTaskNameLength ?
129             p.length : maxTaskNameLength;
130         }
131       }
132       // Print out each entry with descriptions neatly aligned
133       for (p in jake.Task) {
134         if (!Object.prototype.hasOwnProperty.call(jake.Task, p)) {
135           continue;
136         }
137         if (filter && p.indexOf(filter) == -1) {
138           continue;
139         }
140         task = jake.Task[p];
141
142         //name = '\033[32m' + p + '\033[39m ';
143         name = chalk.green(p);
144
145         descr = task.description;
146         if (descr) {
147           descr = chalk.gray('# ' + descr);
148
149           // Create padding-string with calculated length
150           padding = (new Array(maxTaskNameLength - p.length + 2)).join(' ');
151
152           console.log('jake ' + name + padding + descr);
153         }
154       }
155     };
156
157     this.createTask = function () {
158       let args = Array.prototype.slice.call(arguments);
159       let arg;
160       let obj;
161       let task;
162       let type;
163       let name;
164       let action;
165       let opts = {};
166       let prereqs = [];
167
168       type = args.shift();
169
170       // name, [deps], [action]
171       // Name (string) + deps (array) format
172       if (typeof args[0] == 'string') {
173         name = args.shift();
174         if (Array.isArray(args[0])) {
175           prereqs = args.shift();
176         }
177       }
178       // name:deps, [action]
179       // Legacy object-literal syntax, e.g.: {'name': ['depA', 'depB']}
180       else {
181         obj = args.shift();
182         for (let p in obj) {
183           prereqs = prereqs.concat(obj[p]);
184           name = p;
185         }
186       }
187
188       // Optional opts/callback or callback/opts
189       while ((arg = args.shift())) {
190         if (typeof arg == 'function') {
191           action = arg;
192         }
193         else {
194           opts = Object.assign(Object.create(null), arg);
195         }
196       }
197
198       task = jake.currentNamespace.resolveTask(name);
199       if (task && !action) {
200         // Task already exists and no action, just update prereqs, and return it.
201         task.prereqs = task.prereqs.concat(prereqs);
202         return task;
203       }
204
205       switch (type) {
206       case 'directory':
207         action = function () {
208           jake.mkdirP(name);
209         };
210         task = new DirectoryTask(name, prereqs, action, opts);
211         break;
212       case 'file':
213         task = new FileTask(name, prereqs, action, opts);
214         break;
215       default:
216         task = new Task(name, prereqs, action, opts);
217       }
218
219       jake.currentNamespace.addTask(task);
220
221       if (jake.currentTaskDescription) {
222         task.description = jake.currentTaskDescription;
223         jake.currentTaskDescription = null;
224       }
225
226       // FIXME: Should only need to add a new entry for the current
227       // task-definition, not reparse the entire structure
228       jake.parseAllTasks();
229
230       return task;
231     };
232
233     this.attemptRule = function (name, ns, level) {
234       let prereqRule;
235       let prereq;
236       if (level > MAX_RULE_RECURSION_LEVEL) {
237         return null;
238       }
239       // Check Rule
240       prereqRule = ns.matchRule(name);
241       if (prereqRule) {
242         prereq = prereqRule.createTask(name, level);
243       }
244       return prereq || null;
245     };
246
247     this.createPlaceholderFileTask = function (name, namespace) {
248       let parsed = name.split(':');
249       let filePath = parsed.pop(); // Strip any namespace
250       let task;
251
252       task = namespace.resolveTask(name);
253
254       // If there's not already an existing dummy FileTask for it,
255       // create one
256       if (!task) {
257         // Create a dummy FileTask only if file actually exists
258         if (fs.existsSync(filePath)) {
259           task = new jake.FileTask(filePath);
260           task.dummy = true;
261           let ns;
262           if (parsed.length) {
263             ns = namespace.resolveNamespace(parsed.join(':'));
264           }
265           else {
266             ns = namespace;
267           }
268           if (!namespace) {
269             throw new Error('Invalid namespace, cannot add FileTask');
270           }
271           ns.addTask(task);
272           // Put this dummy Task in the global Tasks list so
273           // modTime will be eval'd correctly
274           jake.Task[`${ns.path}:${filePath}`] = task;
275         }
276       }
277
278       return task || null;
279     };
280
281
282     this.run = function () {
283       let args = Array.prototype.slice.call(arguments);
284       let program = this.program;
285       let loader = this.loader;
286       let preempt;
287       let opts;
288
289       program.parseArgs(args);
290       program.init();
291
292       preempt = program.firstPreemptiveOption();
293       if (preempt) {
294         preempt();
295       }
296       else {
297         opts = program.opts;
298         // jakefile flag set but no jakefile yet
299         if (opts.autocomplete && opts.jakefile === true) {
300           process.stdout.write('no-complete');
301           return;
302         }
303         // Load Jakefile and jakelibdir files
304         let jakefileLoaded = loader.loadFile(opts.jakefile);
305         let jakelibdirLoaded = loader.loadDirectory(opts.jakelibdir);
306
307         if(!jakefileLoaded && !jakelibdirLoaded && !opts.autocomplete) {
308           fail('No Jakefile. Specify a valid path with -f/--jakefile, ' +
309               'or place one in the current directory.');
310         }
311
312         program.run();
313       }
314     };
315
316   })());
317 }
318
319 module.exports = jake;