UNPKG

26.2 kBJavaScriptView Raw
1var gulp = require('gulp');
2var gutil = require('gulp-util');
3var jasmine = require('gulp-jasmine');
4var jasmineReporters = require('jasmine-reporters');
5var browserify = require('browserify');
6var _string = require('underscore.string');
7var fs = require('fs');
8var cwd = process.cwd();
9var args = require('./internal/args');
10var logger = require('./internal/logger');
11var notifier = require('./internal/notifier');
12var paths = require('./internal/paths');
13var dependencies = require('./internal/dependecies');
14var maven = require('./internal/maven');
15var bundlegen = require('./internal/bundlegen');
16var ModuleSpec = require('@jenkins-cd/js-modules/js/ModuleSpec');
17var testWebServer;
18var skipBundle = skipBundle();
19var skipTest = (args.isArgvSpecified('--skipTest') || args.isArgvSpecified('--skipTests'));
20var packageJson = require(cwd + '/package.json');
21
22var bundles = []; // see exports.bundle function
23var bundleDependencyTaskNames = ['log-env'];
24
25var rebundleRunning = false;
26var retestRunning = false;
27
28// Make this builder instance globally available.
29global.__builder = exports;
30
31logger.logInfo('**********************************************************************');
32logger.logInfo('This build is using Jenkins JS Builder.');
33logger.logInfo(' For command line options and other help, go to');
34logger.logInfo(' https://www.npmjs.com/package/@jenkins-cd/js-builder');
35logger.logInfo('**********************************************************************');
36
37if (maven.isMavenProject) {
38 logger.logInfo("Maven project.");
39 if (maven.isHPI()) {
40 logger.logInfo("\t- Jenkins plugin (HPI): " + maven.getArtifactId());
41 }
42}
43
44exports.gulp = gulp;
45exports.browserify = browserify;
46
47// Expose the internal modules.
48exports.logger = logger;
49exports.paths = paths;
50exports.dependencies = dependencies;
51exports.maven = maven;
52exports.args = args;
53
54var langConfig = require('./internal/langConfig');
55var lintConfig = {
56 level: 'configured',
57 src: true,
58 tests: false
59};
60
61exports.isRebundle = function() {
62 return rebundleRunning;
63};
64
65exports.isRetest = function() {
66 return retestRunning;
67};
68
69exports.bundleCount = function() {
70 return bundles.length;
71};
72
73/**
74 * Set the JavaScript language configuration.
75 */
76exports.lang = function(config) {
77 if (typeof config === 'number') {
78 langConfig.ecmaVersion = parseInt(config);
79 } else if (typeof config === 'string') {
80 if (config === 'es5') {
81 langConfig.ecmaVersion = 5;
82 } else if (config === 'es6') {
83 langConfig.ecmaVersion = 6;
84 } else if (config === 'react') {
85 langConfig.ecmaVersion = 6;
86 }
87 } else {
88 if (config.ecmaVersion) {
89 langConfig.ecmaVersion = config.ecmaVersion;
90 }
91 }
92 return exports;
93};
94
95/**
96 * Set the lint config.
97 * @param config The lint config. A string of "none", "configured", or
98 * an .
99 */
100exports.lint = function(config) {
101 if (typeof config === 'string') {
102 if (config === 'none') {
103 lintConfig.level = 'none';
104 }
105 } else {
106 if (config.src) {
107 lintConfig.src = config.src;
108 }
109 if (config.tests) {
110 lintConfig.tests = config.tests;
111 }
112 }
113};
114
115exports.defineTasks = function(tasknames) {
116 if (!tasknames) {
117 tasknames = ['test'];
118 }
119
120 var envLogged = false;
121 gulp.task('log-env', function() {
122 if (envLogged === false) {
123 logger.logInfo("Source Dirs:");
124 logger.logInfo(" - src: " + paths.srcPaths);
125 logger.logInfo(" - test: " + paths.testSrcPath);
126 envLogged = true;
127 }
128 });
129
130 var defaults = [];
131
132 for (var i = 0; i < tasknames.length; i++) {
133 var taskname = tasknames[i];
134 var gulpTask = tasks[taskname];
135
136 if (!gulpTask) {
137 throw new Error("Unknown gulp task '" + taskname + "'.");
138 }
139
140 exports.defineTask(taskname, gulpTask);
141 if (taskname === 'lint' || taskname === 'test' || taskname === 'bundle') {
142 defaults.push(taskname);
143 }
144 }
145
146 if (defaults.length > 0) {
147 logger.logInfo('Defining default tasks...');
148 gulp.task('default', defaults);
149 }
150};
151
152exports.defineTask = function(taskname, gulpTask) {
153 if (taskname === 'test') {
154 if (!skipTest) {
155 // Want to make sure the 'bundle' task gets run with the 'test' task.
156 gulp.task('test', ['bundle'], gulpTask);
157 }
158 } else if (taskname === 'bundle') {
159 if (!skipBundle) {
160 // Define the bundle task so that it depends on the "sub" bundle tasks.
161 gulp.task('bundle', bundleDependencyTaskNames, gulpTask);
162 }
163 } else if (taskname === 'bundle:watch') {
164 // Run bundle at the start of bundle:watch
165 gulp.task('bundle:watch', ['bundle'], gulpTask);
166 } else if (taskname === 'test:watch') {
167 // Run test at the start of test:watch
168 gulp.task('test:watch', ['test'], gulpTask);
169 } else {
170 gulp.task(taskname, gulpTask);
171 }
172};
173
174exports.defineBundleTask = function(taskname, gulpTask) {
175 var bundleTaskName = taskname + '_bundle_' + bundleDependencyTaskNames.length;
176
177 bundleDependencyTaskNames.push(bundleTaskName);
178 exports.defineTask(bundleTaskName, gulpTask);
179 // Define the 'bundle' task again so it picks up the new dependency
180 exports.defineTask('bundle', tasks.bundle);
181};
182
183exports.src = function(newPaths) {
184 if (newPaths) {
185 paths.srcPaths = [];
186 if (typeof newPaths === 'string') {
187 paths.srcPaths.push(normalizePath(newPaths));
188 } else if (newPaths.constructor === Array) {
189 for (var i = 0; i < newPaths.length; i++) {
190 paths.srcPaths.push(normalizePath(newPaths[i]));
191 }
192 }
193 }
194 return paths.srcPaths;
195};
196
197exports.tests = function(newPath) {
198 if (newPath) {
199 paths.testSrcPath = normalizePath(newPath);
200 }
201 return paths.testSrcPath;
202};
203
204exports.startTestWebServer = function(config) {
205 _stopTestWebServer();
206 _startTestWebServer(config);
207 logger.logInfo("\t(call require('gulp').emit('testing_completed') when testing is completed - watch async test execution)");
208};
209
210exports.onTaskStart = function(taskName, callback) {
211 gulp.on('task_start', function(event) {
212 if (event.task === taskName) {
213 callback();
214 }
215 });
216};
217
218exports.onTaskEnd = function(taskName, callback) {
219 gulp.on('task_stop', function(event) {
220 if (event.task === taskName) {
221 callback();
222 }
223 });
224};
225
226exports.import = function(module, to, config) {
227 var moduleMapping = toModuleMapping(module, to, config);
228 if (moduleMapping) {
229 bundlegen.addGlobalImportMapping(moduleMapping);
230 }
231 return exports;
232};
233
234exports.export = function(module) {
235 bundlegen.addGlobalExportMapping(module);
236 return exports;
237};
238
239exports.withExternalModuleMapping = function(from, to, config) {
240 logger.logWarn('DEPRECATED use of builder.withExternalModuleMapping function. Change to builder.import.');
241 return exports.import(from, to, config);
242};
243
244/**
245 * Add a listener to be called just before Browserify starts bundling.
246 * <p>
247 * The listener is called with the {@code bundle} as {@code this} and
248 * the {@code bundler} as as the only arg.
249 *
250 * @param listener The listener to add.
251 */
252exports.onPreBundle = function(listener) {
253 bundlegen.onPreBundle(listener);
254 return exports;
255};
256
257/**
258 * Add a listener to be called just after Browserify finishes bundling.
259 * <p>
260 * The listener is called with the {@code bundle} as {@code this} and
261 * the location of the generated bundle as as the only arg.
262 *
263 * @param listener The listener to add.
264 */
265exports.onPostBundle = function(listener) {
266 bundlegen.onPostBundle(listener);
267 return exports;
268};
269
270function normalizePath(path) {
271 path = _string.ltrim(path, './');
272 path = _string.ltrim(path, '/');
273 path = _string.rtrim(path, '/');
274
275 return path;
276}
277
278exports.bundle = function(resource, as) {
279 if (_string.endsWith(resource, '.css')) {
280 return bundleCss(resource, 'css', as);
281 } if (_string.endsWith(resource, '.less')) {
282 return bundleCss(resource, 'less', as);
283 } else {
284 return bundleJs(resource, as);
285 }
286};
287
288function bundleJs(moduleToBundle, as) {
289 if (!moduleToBundle) {
290 gutil.log(gutil.colors.red("Error: Invalid bundle registration for module 'moduleToBundle' must be specify."));
291 throw new Error("'bundle' registration failed. See error above.");
292 }
293
294 var bundle = {};
295
296 bundle.js = _string.strRightBack(moduleToBundle, '/'); // The short name of the javascript file (with extension but without path)
297 bundle.module = _string.strLeftBack(bundle.js, '.js'); // The short name with the .js extension removed
298 bundle.bundleDependencyModule = (moduleToBundle === bundle.module); // The specified module to bundle is the name of a module dependency.
299
300 if (!as) {
301 bundle.as = bundle.module;
302 } else {
303 bundle.as = _string.strLeftBack(as, '.js');
304 }
305
306 bundle.asModuleSpec = new ModuleSpec(bundle.as);
307 var loadBundleFileNamePrefix = bundle.asModuleSpec.getLoadBundleFileNamePrefix();
308 if (loadBundleFileNamePrefix) {
309 bundle.as = loadBundleFileNamePrefix;
310 }
311 bundle.bundleExportNamespace = bundle.asModuleSpec.namespace;
312
313 function assertBundleOutputUndefined() {
314 if (bundle.bundleInDir) {
315 gutil.log(gutil.colors.red("Error: Invalid bundle registration. Bundle output (inDir) already defined."));
316 throw new Error("'bundle' registration failed. See error above.");
317 }
318 }
319
320 bundle.bundleModule = moduleToBundle;
321 bundle.bundleOutputFile = bundle.as + '.js';
322 bundle.moduleMappings = [];
323 bundle.moduleExports = [];
324 bundle.exportEmptyModule = true;
325 bundle.useGlobalImportMappings = true;
326 bundle.useGlobalExportMappings = true;
327 bundle.minifyBundle = args.isArgvSpecified('--minify');
328 bundle.generateNoImportsBundle = function() {
329 if (skipBundle) {
330 return bundle;
331 }
332 // Create a self contained version of the bundle (no imports) - useful for
333 // testing and probably more.
334 defineJSBundleTask(bundle, false);
335 return bundle;
336 };
337 bundle.minify = function() {
338 if (skipBundle) {
339 return bundle;
340 }
341 bundle.minifyBundle = true;
342 return bundle;
343 };
344 bundle.inDir = function(dir) {
345 if (skipBundle) {
346 return bundle;
347 }
348 if (!dir) {
349 gutil.log(gutil.colors.red("Error: Invalid bundle registration for module '" + moduleToBundle + "'. You can't specify a 'null' dir name when calling inDir."));
350 throw new Error("'bundle' registration failed. See error above.");
351 }
352 assertBundleOutputUndefined();
353 bundle.bundleInDir = normalizePath(dir);
354 if (bundle.isDuplicate === false) {
355 gutil.log(gutil.colors.green("Bundle of '" + moduleToBundle + "' will be generated in directory '" + bundle.bundleInDir + "' as '" + bundle.as + ".js'."));
356 }
357 return bundle;
358 };
359 bundle.withTransforms = function(transforms) {
360 if (skipBundle) {
361 return bundle;
362 }
363 bundle.bundleTransforms = transforms;
364 return bundle;
365 };
366
367 bundle.ignoreGlobalImportMappings = function() {
368 bundle.useGlobalImportMappings = false;
369 return bundle;
370 };
371
372 bundle.ignoreGlobalModuleMappings = function() {
373 logger.logWarn('DEPRECATED use of bundle.ignoreGlobalModuleMappings function. Change to bundle.ignoreGlobalImportMappings.');
374 return bundle.ignoreGlobalImportMappings();
375 };
376
377 bundle.ignoreGlobalExportMappings = function() {
378 bundle.useGlobalExportMappings = false;
379 return bundle;
380 };
381
382 bundle.noEmptyModuleExport = function() {
383 bundle.exportEmptyModule = false;
384 return bundle;
385 };
386
387 bundle._import = function(moduleMapping) {
388 if (skipBundle) {
389 return bundle;
390 }
391
392 var toSpec = new ModuleSpec(moduleMapping.to);
393 if (toSpec.importAs() === bundle.importAs()) {
394 // Do not add mappings to itself.
395 return bundle;
396 }
397
398 for (var i in bundle.moduleMappings) {
399 if (bundle.moduleMappings[i].from === moduleMapping.from) {
400 logger.logWarn('Ignoring require mapping of "' + moduleMapping.from + '" to "' + moduleMapping.to + '". The bundle already has a mapping for "' + moduleMapping.from + '".');
401 return bundle;
402 }
403 }
404
405 if (moduleMapping.fromSpec) {
406 bundle.moduleMappings.push(moduleMapping);
407 } else {
408 bundle.moduleMappings.push(toModuleMapping(moduleMapping.from, moduleMapping.to, moduleMapping.config));
409 }
410 return bundle;
411 };
412
413 bundle.import = function(module, to, config) {
414 var moduleMapping = toModuleMapping(module, to, config);
415 bundle._import(moduleMapping);
416 return bundle;
417 };
418
419 bundle.withExternalModuleMapping = function(from, to, config) {
420 logger.logWarn('DEPRECATED use of bundle.withExternalModuleMapping function. Change to bundle.import.');
421 return bundle.import(from, to, config);
422 };
423
424 bundle.less = function(src, targetDir) {
425 if (skipBundle) {
426 return bundle;
427 }
428 bundle.lessSrcPath = src;
429 if (targetDir) {
430 bundle.lessTargetDir = targetDir;
431 }
432 return bundle;
433 };
434 bundle.namespace = function(toNamespace) {
435 bundle.bundleExportNamespace = toNamespace;
436 return bundle;
437 };
438 bundle.export = function(moduleName) {
439 if (skipBundle) {
440 return bundle;
441 }
442 dependencies.assertHasJenkinsJsModulesDependency('Cannot bundle "export".');
443
444 if (moduleName) {
445 if (moduleName === packageJson.name) {
446 // We are exporting the top/entry level module of the generated bundle.
447 // This is the "traditional" export use case.
448 bundle.bundleExport = true;
449 bundle.bundleExportNamespace = packageJson.name;
450 } else if (dependencies.getDependency(moduleName) !== undefined) {
451 // We are exporting some dependency of this module Vs exporting
452 // the top/entry level module of the generated bundle. This allows the bundle
453 // to control loading of a specific dependency (or set of) and then share that with
454 // other bundles, which is needed where we have "singleton" type modules
455 // e.g. react and react-dom.
456 bundle.moduleExports.push(moduleName);
457 } else {
458 logger.logError("Error: Cannot export module '" + moduleName + "' - not the name of this module or one of it's dependencies.");
459 logger.logError(" (if '" + moduleName + "' is the namespace you want to export to, use the 'bundle.namespace' function)");
460 }
461 } else {
462 if (bundle.bundleExportNamespace) {
463 bundle.bundleExport = true;
464 } else if (maven.isMavenProject) {
465 bundle.bundleExport = true;
466 // Use the maven artifactId as the namespace.
467 bundle.bundleExportNamespace = maven.getArtifactId();
468 if (!maven.isHPI()) {
469 logger.logWarn("\t- Bundling process will use the maven pom artifactId ('" + bundle.bundleExportNamespace + "') as the bundle export namespace. You can specify a namespace as a parameter to the 'export' method call.");
470 }
471 } else {
472 logger.logError("Error: This is not a maven project. You must define a namespace via the 'namespace' function on the bundle.");
473 return bundle;
474 }
475 logger.logInfo("\t- Bundle will be exported as '" + bundle.bundleExportNamespace + ":" + bundle.as + "'.");
476 }
477 return bundle;
478 };
479
480 bundle.importAs = function() {
481 if (bundle.bundleExportNamespace && bundle.bundleExportNamespace !== bundle.asModuleSpec.namespace) {
482 var modifiedSpec = new ModuleSpec(bundle.bundleExportNamespace + ':' + bundle.asModuleSpec.getLoadBundleName());
483 return modifiedSpec.importAs();
484 } else {
485 return bundle.asModuleSpec.importAs();
486 }
487 };
488
489 bundle.findModuleMapping = function(from) {
490 var moduleMappings = bundle.moduleMappings;
491 for (var i = 0; i < moduleMappings.length; i++) {
492 var mapping = moduleMappings[i];
493 if (from === mapping.from) {
494 return mapping;
495 }
496 }
497 return undefined;
498 };
499
500 if (skipBundle) {
501 return bundle;
502 }
503
504 bundle.isDuplicate = false;
505 for (var i = 0; i < bundles.length; i++) {
506 if (bundles[i].bundleModule === bundle.bundleModule && bundles[i].as === bundle.as) {
507 bundle.isDuplicate = true;
508 break;
509 }
510 }
511
512 if (bundle.isDuplicate === true) {
513 // Just return the bundle object, but do not register a task
514 // for creating it.
515 return bundle;
516 }
517
518 bundles.push(bundle);
519
520 function defineJSBundleTask(bundle, applyImports) {
521 var bundleTaskName = 'js_bundle_' + bundle.as;
522
523 if (!applyImports) {
524 bundleTaskName += '_no_imports';
525 }
526
527 exports.defineBundleTask(bundleTaskName, function() {
528 return bundlegen.doJSBundle(bundle, applyImports);
529 });
530 }
531
532 // Create a bundle with imports applied/transformed.
533 defineJSBundleTask(bundle, true);
534
535 return bundle;
536}
537
538function bundleCss(resource, format) {
539 var bundle = {
540 format: format
541 };
542
543 var folder = paths.parentDir(resource);
544
545 bundle.fileExtension = '.' + format;
546 bundle.shortName = _string.strRightBack(resource, '/');
547 bundle.as = _string.strLeftBack(bundle.shortName, bundle.fileExtension);
548 bundle.bundleExportNamespace = _string.strRightBack(folder, '/');
549
550 bundle.inDir = function(dir) {
551 if (skipBundle) {
552 return bundle;
553 }
554 if (!dir) {
555 logger.logError("Error: Invalid bundle registration for CSS resource '" + resource + "'. You can't specify a 'null' dir name when calling inDir.");
556 throw new Error("'bundle' registration failed. See error above.");
557 }
558 bundle.bundleInDir = normalizePath(dir);
559 return bundle;
560 };
561
562 var bundleTaskName = format + '_bundle_' + bundle.as;
563 exports.defineBundleTask(bundleTaskName, function() {
564 return bundlegen.doCSSBundle(bundle, resource);
565 });
566
567 return bundle;
568}
569
570function toModuleMapping(from, to, config) {
571 dependencies.assertHasJenkinsJsModulesDependency('Cannot process bundle "import".');
572
573 // 'to' is optional, so maybe the second arg is a
574 // config object.
575 if (to && typeof to === 'object') {
576 config = to;
577 to = undefined;
578 }
579
580 if (config === undefined) {
581 config = {};
582 } else if (typeof config === 'string') {
583 // config is the require mapping override (backward compatibility).
584 config = {
585 require: config
586 };
587 } else {
588 // Clone the config object because we're going to be
589 // making changes to it.
590 config = JSON.parse(JSON.stringify(config));
591 }
592
593 if (!from) {
594 var message = "Cannot call 'import' without defining the 'from' module name.";
595 logger.logError(message);
596 throw new Error(message);
597 }
598
599 var fromSpec = new ModuleSpec(from);
600
601 if (!to) {
602 var adjExt = require('./internal/adjunctexternal');
603 to = adjExt.bundleFor(exports, from);
604 // If still nothing, use a qualified version of the from
605 if (!to) {
606 to = fromSpec.importAs();
607 }
608 }
609
610 // special case because we are externalizing handlebars runtime for handlebarsify.
611 if (from === 'handlebars' && to === 'handlebars:handlebars3' && !config.require) {
612 config.require = 'jenkins-handlebars-rt/runtimes/handlebars3_rt';
613 }
614
615 return {
616 from: from,
617 fromSpec: fromSpec,
618 to: to,
619 config: config
620 };
621}
622
623function buildSrcWatchList(includeTestSrc) {
624 var watchList = [];
625
626 watchList.push('./index.js');
627 for (var i = 0; i < paths.srcPaths.length; i++) {
628 var srcPath = paths.srcPaths[i];
629 watchList.push(srcPath + '/*.*');
630 watchList.push(srcPath + '/**/*.*');
631 }
632
633 if (includeTestSrc && includeTestSrc === true) {
634 watchList.push(paths.testSrcPath + '/**/*.*');
635 }
636
637 return watchList;
638}
639
640function rebundleLogging() {
641 if (rebundleRunning === true) {
642 logger.logInfo('*********************************************');
643 logger.logInfo('bundle:watch: watching for source changes again ...');
644 }
645}
646
647var tasks = {
648 test: function () {
649 if (!paths.testSrcPath) {
650 logger.logWarn("Warn: Test src path has been unset. No tests to run.");
651 return;
652 }
653
654 var terminalReporter = new jasmineReporters.TerminalReporter({
655 verbosity: 3,
656 color: true,
657 showStack: true
658 });
659 var junitReporter = new jasmineReporters.JUnitXmlReporter({
660 savePath: 'target/surefire-reports',
661 consolidateAll: true,
662 filePrefix: 'JasmineReport'
663 });
664
665 var testFileSuffix = args.argvValue('--testFileSuffix', 'spec');
666
667 var testSpecs = paths.testSrcPath + '/**/' + args.argvValue('--test', '') + '*-' + testFileSuffix + '.js';
668 logger.logInfo('Test specs: ' + testSpecs + ' (use --testFileSuffix switch to select different files)');
669
670 global.jenkinsBuilder = exports;
671 _startTestWebServer();
672 gulp.src(testSpecs)
673 .pipe(jasmine({reporter: [terminalReporter, junitReporter, {
674 jasmineDone: function () {
675 gulp.emit('testing_completed');
676 }
677 }]})
678 .on('error', function (err) {
679 logger.logError('Jasmine test failures. See console for details (or surefire JUnit report files in target folder).', err);
680 if (exports.isRebundle() || exports.isRetest()) {
681 notifier.notify('Jasmine test failures', 'See console for details (or surefire JUnit report files in target folder).');
682 // ignore failures if we are running rebundle/retesting.
683 this.emit('end');
684 } else {
685 process.exit(1);
686 }
687 })
688 )
689 ;
690 },
691 bundle: function() {
692 if (bundles.length === 0) {
693 logger.logWarn("Warning: Skipping 'bundle' task. No 'module' bundles are registered. Call require('jenkins-js-build').bundle([module]) in gulpfile.js.");
694 }
695 logger.logInfo('bundling: done');
696 rebundleLogging();
697 },
698 'bundle:watch': function() {
699 var watchList = buildSrcWatchList(false);
700 logger.logInfo('bundle:watch watch list: ' + watchList);
701 rebundleRunning = true;
702 gulp.watch(watchList, ['bundle']);
703 rebundleLogging();
704 },
705 'test:watch': function() {
706 var watchList = buildSrcWatchList(true);
707 logger.logInfo('test:watch watch list: ' + watchList);
708 retestRunning = true;
709 gulp.watch(watchList, ['test']);
710 },
711
712 lint: function() {
713 require('./internal/lint').exec(langConfig, lintConfig);
714 }
715};
716
717function skipBundle() {
718 // Can't skip bundle if there are handlebars file and a dependency on hbsify
719 if (dependencies.getDependency('hbsfy') && paths.hasSourceFiles('hbs')) {
720 return false;
721 }
722
723 return args.isArgvSpecified('--skipBundle');
724}
725
726function _startTestWebServer(config) {
727 if (!config) {
728 config = {}
729 }
730 if (!config.port) {
731 config.port = 18999;
732 }
733 if (!config.root) {
734 config.root = cwd;
735 }
736
737 if (!testWebServer) {
738 // Start a web server that will allow tests to request resources.
739 testWebServer = require('node-http-server').deploy(config);
740 logger.logInfo('Testing web server started on port ' + config.port + ' (http://localhost:' + config.port + '). Content root: ' + config.root);
741 }
742}
743
744gulp.on('testing_completed', function() {
745 _stopTestWebServer();
746 if (retestRunning === true) {
747 logger.logInfo('*********************************************');
748 logger.logInfo('test:watch: watching for source changes again ...');
749 }
750});
751
752function _stopTestWebServer() {
753 if (testWebServer) {
754 testWebServer.close();
755 testWebServer = undefined;
756 logger.logInfo('Testing web server stopped.');
757 }
758}
759
760if (args.isArgvSpecified('--h') || args.isArgvSpecified('--help')) {
761 skipBundle = true;
762 gulp.task('default', function() {});
763} else {
764 // Defined default tasks. Can be overridden.
765 var defaultTasks = [];
766 if (!args.isArgvSpecified('--skipLint')) {
767 defaultTasks.push('lint');
768 } else {
769 gulp.task('lint', function() {
770 logger.logInfo(' - lint skipped (--skipLint)');
771 });
772 }
773 if (!skipTest) {
774 defaultTasks.push('test');
775 } else {
776 gulp.task('test', function() {
777 logger.logInfo(' - tests skipped (--skipTests)');
778 });
779 }
780 if (!skipBundle) {
781 defaultTasks.push('bundle');
782 } else {
783 gulp.task('bundle', function() {
784 logger.logInfo(' - bundle skipped (--skipBundle)');
785 });
786 }
787 defaultTasks.push('bundle:watch');
788 defaultTasks.push('test:watch');
789 exports.defineTasks(defaultTasks);
790
791 dependencies.processExternalizedDependencies(this);
792
793 // Install plugins.
794 require('./internal/plugins').install(exports);
795}
\No newline at end of file