You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
4.9 KiB

  1. /* jshint node:true, camelcase:false */
  2. var gulp = require('gulp');
  3. var del = require('del');
  4. var glob = require('glob');
  5. var karma = require('karma').server;
  6. var merge = require('merge-stream');
  7. var plato = require('plato');
  8. var plug = require('gulp-load-plugins')();
  9. var paths = {
  10. js: './toastr.js',
  11. less: './toastr.less',
  12. report: './report',
  13. build: './build'
  14. };
  15. var colors = plug.util.colors;
  16. var log = plug.util.log;
  17. /**
  18. * List the available gulp tasks
  19. */
  20. gulp.task('help', plug.taskListing);
  21. /**
  22. * Lint the code, create coverage report, and a visualizer
  23. * @return {Stream}
  24. */
  25. gulp.task('analyze', function() {
  26. log('Analyzing source with JSHint, JSCS, and Plato');
  27. var jshint = analyzejshint([paths.js]);
  28. var jscs = analyzejscs([paths.js]);
  29. startPlatoVisualizer();
  30. return merge(jshint, jscs);
  31. });
  32. /**
  33. * Minify and bundle the app's JavaScript
  34. * @return {Stream}
  35. */
  36. gulp.task('js', function() {
  37. log('Bundling, minifying, and copying the app\'s JavaScript');
  38. return gulp
  39. .src(paths.js)
  40. .pipe(plug.sourcemaps.init())
  41. .pipe(plug.bytediff.start())
  42. .pipe(plug.uglify({}))
  43. .pipe(plug.bytediff.stop(bytediffFormatter))
  44. .pipe(plug.sourcemaps.write('.'))
  45. .pipe(plug.rename(function(path) {
  46. if (path.extname === '.js') {
  47. path.basename += '.min';
  48. }
  49. }))
  50. .pipe(gulp.dest(paths.build));
  51. });
  52. /**
  53. * Minify and bundle the CSS
  54. * @return {Stream}
  55. */
  56. gulp.task('css', function() {
  57. log('Bundling, minifying, and copying the app\'s CSS');
  58. return gulp.src(paths.less)
  59. .pipe(plug.less())
  60. // .pipe(plug.autoprefixer('last 2 version', '> 5%'))
  61. .pipe(gulp.dest(paths.build))
  62. .pipe(plug.bytediff.start())
  63. .pipe(plug.minifyCss({}))
  64. .pipe(plug.bytediff.stop(bytediffFormatter))
  65. .pipe(plug.rename('toastr.min.css'))
  66. .pipe(gulp.dest(paths.build));
  67. });
  68. /**
  69. * Build js and css
  70. */
  71. gulp.task('default', ['js', 'css'], function() {
  72. log('Analyze, Build CSS and JS');
  73. });
  74. /**
  75. * Remove all files from the build folder
  76. * One way to run clean before all tasks is to run
  77. * from the cmd line: gulp clean && gulp build
  78. * @return {Stream}
  79. */
  80. gulp.task('clean', function(cb) {
  81. log('Cleaning: ' + plug.util.colors.blue(paths.report));
  82. log('Cleaning: ' + plug.util.colors.blue(paths.build));
  83. var delPaths = [paths.build, paths.report];
  84. del(delPaths, cb);
  85. });
  86. /**
  87. * Run specs once and exit
  88. * To start servers and run midway specs as well:
  89. * gulp test --startServers
  90. * @return {Stream}
  91. */
  92. gulp.task('test', function(done) {
  93. startTests(true /*singleRun*/ , done);
  94. });
  95. ////////////////
  96. /**
  97. * Execute JSHint on given source files
  98. * @param {Array} sources
  99. * @param {String} overrideRcFile
  100. * @return {Stream}
  101. */
  102. function analyzejshint(sources, overrideRcFile) {
  103. var jshintrcFile = overrideRcFile || './.jshintrc';
  104. log('Running JSHint');
  105. return gulp
  106. .src(sources)
  107. .pipe(plug.jshint(jshintrcFile))
  108. .pipe(plug.jshint.reporter('jshint-stylish'));
  109. }
  110. /**
  111. * Execute JSCS on given source files
  112. * @param {Array} sources
  113. * @return {Stream}
  114. */
  115. function analyzejscs(sources) {
  116. log('Running JSCS');
  117. return gulp
  118. .src(sources)
  119. .pipe(plug.jscs('./.jscsrc'));
  120. }
  121. /**
  122. * Start Plato inspector and visualizer
  123. */
  124. function startPlatoVisualizer() {
  125. log('Running Plato');
  126. var files = glob.sync('toastr.js');
  127. var options = {
  128. title: 'Plato Inspections Report'
  129. };
  130. var outputDir = './report/plato';
  131. plato.inspect(files, outputDir, options, platoCompleted);
  132. function platoCompleted(report) {
  133. var overview = plato.getOverviewReport(report);
  134. log(overview.summary);
  135. }
  136. }
  137. /**
  138. * Start the tests using karma.
  139. * @param {boolean} singleRun - True means run once and end (CI), or keep running (dev)
  140. * @param {Function} done - Callback to fire when karma is done
  141. * @return {undefined}
  142. */
  143. function startTests(singleRun, done) {
  144. karma.start({
  145. configFile: __dirname + '/karma.conf.js',
  146. singleRun: !!singleRun
  147. }, karmaCompleted);
  148. ////////////////
  149. function karmaCompleted() {
  150. done();
  151. }
  152. }
  153. /**
  154. * Formatter for bytediff to display the size changes after processing
  155. * @param {Object} data - byte data
  156. * @return {String} Difference in bytes, formatted
  157. */
  158. function bytediffFormatter(data) {
  159. var difference = (data.savings > 0) ? ' smaller.' : ' larger.';
  160. return data.fileName + ' went from ' +
  161. (data.startSize / 1000).toFixed(2) + ' kB to ' + (data.endSize / 1000).toFixed(2) + ' kB' +
  162. ' and is ' + formatPercent(1 - data.percent, 2) + '%' + difference;
  163. }
  164. /**
  165. * Format a number as a percentage
  166. * @param {Number} num Number to format as a percent
  167. * @param {Number} precision Precision of the decimal
  168. * @return {Number} Formatted perentage
  169. */
  170. function formatPercent(num, precision) {
  171. return (num * 100).toFixed(precision);
  172. }