UNPKG

15.1 kBJavaScriptView Raw
1"use strict";
2// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3// See LICENSE in the project root for license information.
4function __export(m) {
5 for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
6}
7Object.defineProperty(exports, "__esModule", { value: true });
8if (process.argv.indexOf('--no-color') === -1) {
9 process.argv.push('--color');
10}
11const path = require("path");
12const GulpTask_1 = require("./tasks/GulpTask");
13const GulpProxy_1 = require("./GulpProxy");
14const CleanTask_1 = require("./tasks/CleanTask");
15const CleanFlagTask_1 = require("./tasks/CleanFlagTask");
16const CopyStaticAssetsTask_1 = require("./tasks/copyStaticAssets/CopyStaticAssetsTask");
17const State_1 = require("./State");
18const logging_1 = require("./logging");
19const logging_2 = require("./logging");
20const config_1 = require("./config");
21const notifier = require("node-notifier");
22const JestTask_1 = require("./tasks/JestTask");
23var logging_3 = require("./logging");
24exports.addSuppression = logging_3.addSuppression;
25exports.coverageData = logging_3.coverageData;
26exports.functionalTestRun = logging_3.functionalTestRun;
27exports.getErrors = logging_3.getErrors;
28exports.getWarnings = logging_3.getWarnings;
29exports.TestResultState = logging_3.TestResultState;
30exports.warn = logging_3.warn;
31exports.verbose = logging_3.verbose;
32exports.error = logging_3.error;
33exports.fileError = logging_3.fileError;
34exports.fileLog = logging_3.fileLog;
35exports.fileWarning = logging_3.fileWarning;
36exports.reset = logging_3.reset;
37exports.log = logging_3.log;
38exports.logSummary = logging_3.logSummary;
39__export(require("./tasks/CopyTask"));
40__export(require("./tasks/GenerateShrinkwrapTask"));
41__export(require("./tasks/GulpTask"));
42__export(require("./tasks/CleanTask"));
43__export(require("./tasks/CleanFlagTask"));
44__export(require("./tasks/ValidateShrinkwrapTask"));
45__export(require("./tasks/copyStaticAssets/CopyStaticAssetsTask"));
46__export(require("./tasks/JestTask"));
47const _taskMap = {};
48const _uniqueTasks = [];
49const packageFolder = (State_1.builtPackage.directories && State_1.builtPackage.directories.packagePath)
50 ? State_1.builtPackage.directories.packagePath
51 : '';
52let _buildConfig = {
53 maxBuildTimeMs: 0,
54 // gulp and rootPath are set to undefined here because they'll be defined in the initialize function below,
55 // but we don't want their types to be nullable because a task that uses StrictNullChecks should expect them
56 // to be defined without checking their values.
57 gulp: undefined,
58 rootPath: undefined,
59 packageFolder,
60 srcFolder: 'src',
61 distFolder: path.join(packageFolder, 'dist'),
62 libAMDFolder: undefined,
63 libESNextFolder: undefined,
64 libFolder: path.join(packageFolder, 'lib'),
65 tempFolder: 'temp',
66 properties: {},
67 relogIssues: config_1.getFlagValue('relogIssues', true),
68 showToast: config_1.getFlagValue('showToast', true),
69 buildSuccessIconPath: path.resolve(__dirname, 'pass.png'),
70 buildErrorIconPath: path.resolve(__dirname, 'fail.png'),
71 verbose: config_1.getFlagValue('verbose', false),
72 production: config_1.getFlagValue('production', false),
73 args: State_1.args,
74 shouldWarningsFailBuild: false
75};
76/**
77 * Merges the given build config settings into existing settings.
78 *
79 * @param config - The build config settings.
80 * @public
81 */
82function setConfig(config) {
83 // eslint-disable-next-line
84 const objectAssign = require('object-assign');
85 _buildConfig = objectAssign({}, _buildConfig, config);
86}
87exports.setConfig = setConfig;
88/**
89 * Merges the given build config settings into existing settings.
90 *
91 * @param config - The build config settings.
92 * @public
93 */
94function mergeConfig(config) {
95 // eslint-disable-next-line
96 const merge = require('lodash.merge');
97 _buildConfig = merge({}, _buildConfig, config);
98}
99exports.mergeConfig = mergeConfig;
100/**
101 * Replaces the build config.
102 *
103 * @param config - The build config settings.
104 * @public
105 */
106function replaceConfig(config) {
107 _buildConfig = config;
108}
109exports.replaceConfig = replaceConfig;
110/**
111 * Gets the current config.
112 * @returns the current build configuration
113 * @public
114 */
115function getConfig() {
116 return _buildConfig;
117}
118exports.getConfig = getConfig;
119/** @public */
120exports.cleanFlag = new CleanFlagTask_1.CleanFlagTask();
121/**
122 * Registers an IExecutable to gulp so that it can be called from the command line
123 * @param taskName - the name of the task, can be called from the command line (e.g. "gulp <taskName>")
124 * @param taskExecutable - the executable to execute when the task is invoked
125 * @returns the task parameter
126 * @public
127 */
128function task(taskName, taskExecutable) {
129 taskExecutable = serial(exports.cleanFlag, taskExecutable);
130 _taskMap[taskName] = taskExecutable;
131 _trackTask(taskExecutable);
132 return taskExecutable;
133}
134exports.task = task;
135/** @public */
136class CustomTask extends GulpTask_1.GulpTask {
137 constructor(name, fn) {
138 super(name);
139 this._fn = fn.bind(this);
140 }
141 executeTask(gulp, completeCallback) {
142 return this._fn(gulp, getConfig(), completeCallback);
143 }
144}
145/**
146 * Creates a new subtask from a function callback. Useful as a shorthand way
147 * of defining tasks directly in a gulpfile.
148 *
149 * @param taskName - the name of the task, appearing in build logs
150 * @param fn - the callback function to execute when this task runs
151 * @returns an IExecutable which can be registered to the command line with task()
152 * @public
153 */
154function subTask(taskName, fn) {
155 const customTask = new CustomTask(taskName, fn);
156 return customTask;
157}
158exports.subTask = subTask;
159/**
160 * Defines a gulp watch and maps it to a given IExecutable.
161 *
162 * @param watchMatch - the list of files patterns to watch
163 * @param taskExecutable - the task to execute when a file changes
164 * @returns IExecutable
165 * @public
166 */
167function watch(watchMatch, taskExecutable) {
168 _trackTask(taskExecutable);
169 let isWatchRunning = false;
170 let shouldRerunWatch = false;
171 let lastError = undefined;
172 const successMessage = 'Build succeeded';
173 const failureMessage = 'Build failed';
174 return {
175 execute: (buildConfig) => {
176 return new Promise(() => {
177 function _runWatch() {
178 if (isWatchRunning) {
179 shouldRerunWatch = true;
180 return Promise.resolve();
181 }
182 else {
183 isWatchRunning = true;
184 return _executeTask(taskExecutable, buildConfig)
185 .then(() => {
186 if (lastError) {
187 lastError = undefined;
188 if (buildConfig.showToast) {
189 notifier.notify({
190 title: successMessage,
191 message: (State_1.builtPackage ? State_1.builtPackage.name : ''),
192 icon: buildConfig.buildSuccessIconPath
193 });
194 }
195 else {
196 logging_1.log(successMessage);
197 }
198 }
199 return _finalizeWatch();
200 })
201 .catch((error) => {
202 if (!lastError || lastError !== error) {
203 lastError = error;
204 if (buildConfig.showToast) {
205 notifier.notify({
206 title: failureMessage,
207 message: error.toString(),
208 icon: buildConfig.buildErrorIconPath
209 });
210 }
211 else {
212 logging_1.log(failureMessage);
213 }
214 }
215 return _finalizeWatch();
216 });
217 }
218 }
219 function _finalizeWatch() {
220 isWatchRunning = false;
221 if (shouldRerunWatch) {
222 shouldRerunWatch = false;
223 return _runWatch();
224 }
225 return Promise.resolve();
226 }
227 logging_2.setWatchMode();
228 buildConfig.gulp.watch(watchMatch, _runWatch);
229 _runWatch().catch(console.error);
230 });
231 }
232 };
233}
234exports.watch = watch;
235/**
236 * Takes in IExecutables as arguments and returns an IExecutable that will execute them in serial.
237 * @public
238 */
239function serial(...tasks) {
240 const flatTasks = _flatten(tasks).filter(taskExecutable => {
241 // eslint-disable-next-line @rushstack/no-null
242 return taskExecutable !== null && taskExecutable !== undefined;
243 });
244 for (const flatTask of flatTasks) {
245 _trackTask(flatTask);
246 }
247 return {
248 execute: (buildConfig) => {
249 let output = Promise.resolve();
250 for (const taskExecutable of flatTasks) {
251 output = output.then(() => _executeTask(taskExecutable, buildConfig));
252 }
253 return output;
254 }
255 };
256}
257exports.serial = serial;
258/**
259 * Takes in IExecutables as arguments and returns an IExecutable that will execute them in parallel.
260 * @public
261 */
262function parallel(...tasks) {
263 const flatTasks = _flatten(tasks).filter(taskExecutable => {
264 // eslint-disable-next-line @rushstack/no-null
265 return taskExecutable !== null && taskExecutable !== undefined;
266 });
267 for (const flatTask of flatTasks) {
268 _trackTask(flatTask);
269 }
270 return {
271 // eslint-disable-next-line @typescript-eslint/no-explicit-any
272 execute: (buildConfig) => {
273 return new Promise((resolve, reject) => {
274 const promises = [];
275 for (const taskExecutable of flatTasks) {
276 promises.push(_executeTask(taskExecutable, buildConfig));
277 }
278 // Use promise all to make sure errors are propagated correctly
279 Promise.all(promises).then(resolve, reject);
280 });
281 }
282 };
283}
284exports.parallel = parallel;
285/**
286 * Initializes the gulp tasks.
287 * @public
288 */
289function initialize(gulp) {
290 _buildConfig.rootPath = process.cwd();
291 _buildConfig.gulp = new GulpProxy_1.GulpProxy(gulp);
292 _buildConfig.uniqueTasks = _uniqueTasks;
293 _buildConfig.jestEnabled = JestTask_1._isJestEnabled(_buildConfig.rootPath);
294 _handleCommandLineArguments();
295 for (const uniqueTask of _buildConfig.uniqueTasks) {
296 if (uniqueTask.onRegister) {
297 uniqueTask.onRegister();
298 }
299 }
300 logging_2.initialize(gulp, getConfig(), undefined, undefined);
301 Object.keys(_taskMap).forEach(taskName => _registerTask(gulp, taskName, _taskMap[taskName]));
302 logging_2.markTaskCreationTime();
303}
304exports.initialize = initialize;
305/**
306 * Registers a given gulp task given a name and an IExecutable.
307 */
308function _registerTask(gulp, taskName, taskExecutable) {
309 gulp.task(taskName, (cb) => {
310 const maxBuildTimeMs = taskExecutable.maxBuildTimeMs === undefined
311 ? _buildConfig.maxBuildTimeMs
312 : taskExecutable.maxBuildTimeMs;
313 const timer = maxBuildTimeMs === 0
314 ? undefined
315 : setTimeout(() => {
316 logging_1.error(`Build ran for ${maxBuildTimeMs} milliseconds without completing. Cancelling build with error.`);
317 cb(new Error('Timeout'));
318 }, maxBuildTimeMs);
319 _executeTask(taskExecutable, _buildConfig).then(() => {
320 if (timer) {
321 clearTimeout(timer);
322 }
323 cb();
324 }, (error) => {
325 if (timer) {
326 clearTimeout(timer);
327 }
328 cb(logging_2.generateGulpError(error));
329 });
330 });
331}
332/**
333 * Executes a given IExecutable.
334 */
335function _executeTask(taskExecutable, buildConfig) {
336 // Try to fallback to the default task if provided.
337 if (taskExecutable && !taskExecutable.execute) {
338 // eslint-disable-next-line @typescript-eslint/no-explicit-any
339 if (taskExecutable.default) {
340 // eslint-disable-next-line @typescript-eslint/no-explicit-any
341 taskExecutable = taskExecutable.default;
342 }
343 }
344 // If the task is missing, throw a meaningful error.
345 if (!taskExecutable || !taskExecutable.execute) {
346 return Promise.reject(new Error(`A task was scheduled, but the task was null. This probably means the task wasn't imported correctly.`));
347 }
348 if (taskExecutable.isEnabled === undefined || taskExecutable.isEnabled(buildConfig)) {
349 const startTime = process.hrtime();
350 if (buildConfig.onTaskStart && taskExecutable.name) {
351 buildConfig.onTaskStart(taskExecutable.name);
352 }
353 const taskPromise = taskExecutable.execute(buildConfig)
354 .then(() => {
355 if (buildConfig.onTaskEnd && taskExecutable.name) {
356 buildConfig.onTaskEnd(taskExecutable.name, process.hrtime(startTime));
357 }
358 }, (error) => {
359 if (buildConfig.onTaskEnd && taskExecutable.name) {
360 buildConfig.onTaskEnd(taskExecutable.name, process.hrtime(startTime), error);
361 }
362 return Promise.reject(error);
363 });
364 return taskPromise;
365 }
366 // No-op otherwise.
367 return Promise.resolve();
368}
369function _trackTask(taskExecutable) {
370 if (_uniqueTasks.indexOf(taskExecutable) < 0) {
371 _uniqueTasks.push(taskExecutable);
372 }
373}
374/**
375 * Flattens a set of arrays into a single array.
376 */
377function _flatten(oArr) {
378 const output = [];
379 function traverse(arr) {
380 for (let i = 0; i < arr.length; ++i) {
381 if (Array.isArray(arr[i])) {
382 traverse(arr[i]);
383 }
384 else {
385 output.push(arr[i]);
386 }
387 }
388 }
389 traverse(oArr);
390 return output;
391}
392function _handleCommandLineArguments() {
393 _handleTasksListArguments();
394}
395function _handleTasksListArguments() {
396 /* eslint-disable dot-notation */
397 if (State_1.args['tasks'] || State_1.args['tasks-simple'] || State_1.args['T']) {
398 global['dontWatchExit'] = true;
399 }
400 if (State_1.args['h']) {
401 // we are showing a help command prompt via yargs or ts-command-line
402 global['dontWatchExit'] = true;
403 }
404 /* eslint-enable dot-notation */
405}
406/** @public */
407exports.clean = new CleanTask_1.CleanTask();
408/** @public */
409exports.copyStaticAssets = new CopyStaticAssetsTask_1.CopyStaticAssetsTask();
410/** @public */
411exports.jest = new JestTask_1.JestTask();
412// Register default clean task.
413task('clean', exports.clean);
414//# sourceMappingURL=index.js.map
\No newline at end of file