var gulp = require('gulp'), // Used to process `include` statements in source files includer = require('gulp-includer'), // Compiles SASS files using LibSass sass = require('gulp-sass'), // Renames files in the file stream rename = require('gulp-rename'), // JavaScript minifier uglify = require('gulp-uglify'), // Filter files out of the vinyl stream filter = require('gulp-filter'), // Creates zip files zip = require('gulp-zip'), // CSS minifier csso = require('gulp-csso'), // Used for working with streams es = require('event-stream'), // File system utilities fs = require('fs'), // Search for files/directories matching certain patterns - regex-lite glob = require('glob'), // Used for working with file system paths path = require('path'), // Promise library used in more complex tasks (like `zip`) Q = require('q'); // TODO: Implement something like MEF, where we scan for particular JSON files, // and then assemble this config by merging all of the contents. var pathConfig = { ScriptSrc : 'Scripts/src', // These three core files are required by damn near everything, so instead // of processing them over and over again, we'll process them once in the // `core` task and then include the output files (i.e. the ones not under // `/Scripts/src`) instead of the `src` version to cut down on needless // repetition of the include process. models : 'Scripts/models', Graph : 'Scripts/graph', Report : 'Scripts/report', Collectors : 'Scripts/src/report/collectors', ReportTemplates : 'Scripts/src/report/template', // Foo FooBasePkg : 'Packages/src/Bar', FooAuditPkg : 'Packages/src/Bar/Foo Audit', FooSvaAuditPkg : 'Packages/src/Bar/Foo SVA Audit', FooSvaUnitPkg : 'Packages/src/Bar/Foo SVA Unit', FooUnitPkg : 'Packages/src/Bar/Foo Unit', FooDealerTradePkg : 'Packages/src/Bar/Foo Dealer Trade', FooManualAuditPkg : 'Packages/src/Bar/Foo Manual Audit', FooManualUnitPkg : 'Packages/src/Bar/Foo Manual Unit', FooPartialInventoryAuditPkg: 'Packages/src/Bar/Foo Partial Inventory Audit', FooPartialInventoryUnitPkg : 'Packages/src/Bar/Foo Partial Inventory Unit', // Bar BarBasePkg : 'Packages/src/Bar', BarDscAuditPkg : 'Packages/src/Bar/DSC Audit', BarDscUnitPkg : 'Packages/src/Bar/DSC Unit', BarHondaAuditPkg : 'Packages/src/Bar/Honda Audit', BarHondaAutoPkg : 'Packages/src/Bar/Honda Auto', BarHondaMotoEtAlPkg : 'Packages/src/Bar/Honda Moto, Utility, Watercraft and Marine', BarHondaPePkg : 'Packages/src/Bar/Honda PE', BarManualAuditPkg : 'Packages/src/Bar/Manual Audit', BarManualUnitPkg : 'Packages/src/Bar/Manual Unit', // Test Client TestClientBasePkg : 'Packages/src/TestClient', TestClientTcAuditPkg : 'Packages/src/TestClient/TC Audit' }; // Where to save our package zip files var packageZipDest = '../../Shared'; // Files to copy var themeSourceFiles = [ 'Content/Layouts/Layout.html', 'Content/themes/default.min.css' ], // Factor these out to make structure changes easier themeDestPrefix = 'Packages/bin', themeDestSuffix = '/Reporting', // All of the packages that require Layout.html and default.min.css themeDests = [ '/Bar/DSC Audit', '/Bar/Honda Audit', '/Bar/Manual Audit', '/Bar/Foo Audit', '/Bar/Foo SVA Audit', '/Bar/Foo Manual Audit', '/Bar/Foo Partial Inventory Audit' ]; // Used by the `gulp-rename` plugin to rename `foo.combined.js` to `foo.min.js`. var combined2min = function (path) { path.basename = path.basename.replace('.combined', '.min'); }; // We use the same includer options in every task, so just define them here to // avoid code duplication. var includerOpts = { // By default includer will wrap each include in an immediately-executing // closure, so override the `wrap` method with a simple identify function. wrap: function (src) { return src; }, // Pass the aliases defined above to includer to resolve path mappings. paths: pathConfig }; // Processes the three "core" files that are used in a majority of other // packages. This is a dependency of both the `scripts` and `packages` tasks, // which allows the files handled by those tasks to include the output of this // task when requiring any of these three files, rather than recursively // building these files over and over again, which is what would happen if // the `@Report`, `@models`, and `@Graph` mappings above pointing to the // versions in the `Scripts/src` directory instead. gulp.task('core', function () { // If we want tasks dependent on this task to wait until this task has // completely finished before they themselves execute, we have to return // the pipeline. return gulp.src([ './Scripts/src/**/models.combined.js', './Scripts/src/**/graph.combined.js', './Scripts/src/**/report.combined.js' ], // Because nothing but includer actually needs to know the contents // of the files (and it will handle its own reading), tell gulp not // to bother reading the file content - just pass the paths along. { read: false } ) .pipe(includer(includerOpts)) .pipe(gulp.dest('./Scripts')); }); // Processes includes in all JavaScript files under `Scripts/src` and writes // the output to the base `Scripts` directory while preserving folder structure. // Make sure the `core` task executes completely before this runs. gulp.task('scripts', ['core'], function () { // Because the `core` task has already handled processing these three files, // filter them out from the file stream to avoid processing them again. var coreFilter = filter('**/!(models.combined|graph.combined|report.combined).js'); return gulp.src('./Scripts/src/**/*.combined.js', { read: false }) // Here we pass the file stream through the filter defined above. .pipe(coreFilter) // Now that we've filtered out the files we don't want to process, // pass the files that remain to includer. .pipe(includer(includerOpts)) .pipe(gulp.dest('./Scripts')); }); // Minifies all processed `*.combined.js` files in 'Scripts' (i.e. the files NOT // in the `Scripts/src` directory, which are unprocessed) and writes them to // disk as `*.min.js`. Make sure the `scripts` task executes completely before // this runs. Get the right fileset by first retrieving all *.combined.js files, // then removing any files from `Scripts/src`. gulp.task('scriptMin', ['scripts'], function () { return gulp.src(['Scripts/**/*.combined.js', '!Scripts/src{,/**}']) .pipe(uglify()) .pipe(rename(combined2min)) .pipe(gulp.dest('./Scripts')); }); // Processes includes in all JavaScript files under `Packages/src` and writes // the output to the base `Packages/bin` directory while preserving the folder // structure. Make sure the `scripts` task executes completely before this runs. gulp.task('packages', ['scripts'], function () { return gulp.src('./Packages/src/**/*.combined.js', { read: false }) .pipe(includer(includerOpts)) .pipe(gulp.dest('./Packages/bin')); }); // Minifies all processed `*.combined.js` files in `Packages` (i.e. the files // NOT in the `Packages/src` directory, which are unprocessed) and writes them // to disk as `*.min.js`. Make sure the `packages` task executes completely // before this runs. You can't use a directory negation in the middle of a glob // (whoops) so instead you have to basically do a diff between "all combined // files" and "all files in Packages/src". gulp.task('packageMin', ['packages'], function () { return gulp.src(['Packages/bin/**/*.combined.js']) .pipe(uglify()) .pipe(rename(combined2min)) .pipe(gulp.dest('./Packages/bin')); }); // Copies all of the txt, JSON, html, etc. files that exist in the // `Packages/src` directory tree to the root `Packages` tree. Apparently // glob wildcards have some undocumented bugs, because this was previously // just `gulp.src('Packages/src/!(*.js)')`, but that omitted .JSON files // as well as .js files. gulp.task('packageCopy', function () { return gulp.src(['Packages/src/**/*.*', '!Packages/src/**/*.js']) .pipe(gulp.dest('./Packages/bin')); }); // Compile all `*.scss` files and write their output to the `/Content` // directory. The existing folder structure will be preserved. gulp.task('sass', function () { return gulp.src('./Content/**/*.scss', { read: false }) .pipe(sass({outputStyle: 'nested'})) .pipe(gulp.dest('./Content')); }); // Minifies the CSS output by the SASS compiler, and saves the file as // filename.min.css. Makes sure the `SASS` task runs before this task executes. gulp.task('cssMin', ['sass'], function () { return gulp.src('./Content/**/!(*.min).css', { read: false }) .pipe(csso()) .pipe(rename(function (path) { path.basename += '.min'; })) .pipe(gulp.dest('./Content')); }); // Copies the `Layout.html` and `default.min.css` files from the /Content dir // into the package directories where they are used. Make sure the `sass` task // executes completely before this runs. gulp.task('themeDist', ['cssMin'], function () { var i, il, stream, merged; for (i=0, il=themeDests.length; i