2 * Jake JavaScript build tool
3 * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 let fs = require('fs');
20 let parseargs = require('./parseargs');
21 let utils = require('./utils');
23 let usage = require('fs').readFileSync(`${__dirname}/../usage.txt`).toString();
24 let { Task } = require('./task/task');
28 process.stdout.write('', function () {
29 process.stderr.write('', function () {
36 version: function () {
44 let AVAILABLE_OPTS = [
57 { full: 'always-make',
92 { full: 'allow-rejection',
98 Program = function () {
99 this.availableOpts = AVAILABLE_OPTS;
101 this.taskNames = null;
102 this.taskArgs = null;
107 Program.prototype = new (function () {
109 this.handleErr = function (err) {
110 if (jake.listeners('error').length !== 0) {
111 jake.emit('error', err);
115 if (jake.listeners('error').length) {
116 jake.emit('error', err);
120 utils.logger.error('jake aborted.');
122 utils.logger.error(err.stack);
125 utils.logger.error(err.message);
128 process.stdout.write('', function () {
129 process.stderr.write('', function () {
130 jake.errorCode = jake.errorCode || 1;
131 process.exit(jake.errorCode);
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);
143 this.setOpts = function (options) {
144 let opts = options || {};
145 Object.assign(this.opts, opts);
148 this.internalOpts = function (options) {
149 this.availableOpts = this.availableOpts.concat(options);
152 this.autocompletions = function (cur) {
153 let p; let i; let task;
154 let commonPrefix = '';
157 for (p in jake.Task) {
162 // if empty string, program converts to true
164 task.fullName.indexOf(cur) === 0
167 if (matches.length === 0) {
168 commonPrefix = task.fullName;
171 for (i = commonPrefix.length; i > -1; --i) {
172 commonPrefix = commonPrefix.substr(0, i);
173 if (task.fullName.indexOf(commonPrefix) === 0) {
178 matches.push(task.fullName);
182 if (matches.length > 1 && commonPrefix === cur) {
183 matches.unshift('yes-space');
186 matches.unshift('no-space');
189 process.stdout.write(matches.join(' '));
192 this.setTaskNames = function (names) {
193 if (names && !Array.isArray(names)) {
194 throw new Error('Task names must be an array');
196 this.taskNames = (names && names.length) ? names : ['default'];
199 this.setEnvVars = function (vars) {
200 this.envVars = vars || null;
203 this.firstPreemptiveOption = function () {
204 let opts = this.opts;
205 for (let p in opts) {
213 this.init = function (configuration) {
215 let config = configuration || {};
216 if (config.options) {
217 this.setOpts(config.options);
219 if (config.taskNames) {
220 this.setTaskNames(config.taskNames);
222 if (config.envVars) {
223 this.setEnvVars(config.envVars);
225 process.addListener('uncaughtException', function (err) {
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);
235 Object.assign(process.env, this.envVars);
239 this.run = function () {
243 let opts = this.opts;
245 if (opts.autocomplete) {
246 return this.autocompletions(opts['autocomplete-cur'], opts['autocomplete-prev']);
248 // Run with `jake -T`, just show descriptions
250 return jake.showAllTaskDescriptions(opts.tasks);
253 taskNames = this.taskNames;
254 if (!(Array.isArray(taskNames) && taskNames.length)) {
255 throw new Error('Please pass jake.runTasks an array of task-names');
259 dirname = opts.directory;
261 if (fs.existsSync(dirname) &&
262 fs.statSync(dirname).isDirectory()) {
263 process.chdir(dirname);
266 throw new Error(dirname + ' is not a valid directory path');
270 rootTask = task(Task.ROOT_TASK_NAME, taskNames, function () {});
271 rootTask._internal = true;
273 rootTask.once('complete', function () {
274 jake.emit('complete');
282 module.exports.Program = Program;