From: Gustavo Martin Morcuende Date: Mon, 24 Aug 2015 20:25:02 +0000 (+0200) Subject: gulp: gulp-my-tasks, npm module for running my gulp tasks X-Git-Url: https://git.gumartinm.name/?a=commitdiff_plain;h=7fb3f323f14e8ceefdf5f7cacdf0d83dcae6b586;p=JavaScriptForFun gulp: gulp-my-tasks, npm module for running my gulp tasks In this way I should be able to use the same tasks in any AngularJS project (if it follows my patterns) --- diff --git a/gulp/gulp-my-tasks/index.js b/gulp/gulp-my-tasks/index.js new file mode 100644 index 0000000..97958dd --- /dev/null +++ b/gulp/gulp-my-tasks/index.js @@ -0,0 +1,3 @@ +module.exports = function(gulp, config){ + require(__dirname + '/tasks/tasks.js')(gulp, config) +}; diff --git a/gulp/gulp-my-tasks/package.json b/gulp/gulp-my-tasks/package.json new file mode 100644 index 0000000..16cbd2b --- /dev/null +++ b/gulp/gulp-my-tasks/package.json @@ -0,0 +1,58 @@ +{ + "name": "gulp-my-tasks", + "version": "0.0.1", + "description": "Gulp tasks for AngularJS projects", + "author": { + "name": "Gustavo Martin Morcuende", + "email": "noemail@noemail.invalid", + "url": "http://gumartinm.name" + }, + "homepage": "http://gumartinm.name", + "license": "Apache-2.0", + "main" : "index.js", + "dependencies": { + "del": "~1.2.1", + "express": "~4.13.3", + "express-http-proxy": "~0.6.0", + "extend": "~3.0.0", + "gulp-angular-filesort": "~1.1.1", + "gulp-angular-templatecache": "~1.7.0", + "gulp-batch": "~1.0.5", + "gulp-bytediff": "~1.0.0", + "gulp-filter": "~3.0.0", + "gulp-header": "~1.2.2", + "gulp-htmlhint": "~0.3.0", + "gulp-if": "~1.2.5", + "gulp-inject": "~1.5.0", + "gulp-jscs": "~2.0.0", + "gulp-jshint": "~1.11.2", + "gulp-load-plugins": "~1.0.0-rc.1", + "gulp-minify-css": "~1.2.0", + "gulp-minify-html": "~1.0.4", + "gulp-ng-annotate": "~1.1.0", + "gulp-ngdocs": "~0.2.13", + "gulp-nodemon": "~2.0.3", + "gulp-order": "~1.1.1", + "gulp-print": "~1.1.0", + "gulp-rev": "~5.1.0", + "gulp-rev-replace": "~0.4.2", + "gulp-task-listing": "~1.0.1", + "gulp-uglify": "~1.2.0", + "gulp-useref": "~1.3.0", + "gulp-util": "~3.0.6", + "gulp-watch": "~4.3.5", + "jshint-stylish": "~2.0.1", + "karma": "~0.13.9", + "karma-coverage": "~0.5.0", + "karma-jasmine": "~0.3.6", + "karma-junit-reporter": "~0.3.3", + "karma-phantomjs-launcher": "~0.2.1", + "morgan": "~1.6.1", + "serve-favicon": "~2.3.0", + "wiredep": "~3.0.0-beta", + "yargs": "~3.19.0" + }, + "devDependencies": { + "gulp": "~3.9.0" + } +} diff --git a/gulp/gulp-my-tasks/tasks/.htmlhintrc b/gulp/gulp-my-tasks/tasks/.htmlhintrc new file mode 100644 index 0000000..dc75d5f --- /dev/null +++ b/gulp/gulp-my-tasks/tasks/.htmlhintrc @@ -0,0 +1,14 @@ +{ + "tagname-lowercase": true, + "attr-lowercase": true, + "attr-value-double-quotes": true, + "attr-value-not-empty": false, + "attr-no-duplication" : true, + "doctype-first": true, + "tag-pair": true, + "tag-self-close": false, + "spec-char-escape": true, + "id-unique": true, + "src-not-empty": true, + "head-script-disabled": false +} \ No newline at end of file diff --git a/gulp/gulp-my-tasks/tasks/.jscsrc b/gulp/gulp-my-tasks/tasks/.jscsrc new file mode 100644 index 0000000..194fb59 --- /dev/null +++ b/gulp/gulp-my-tasks/tasks/.jscsrc @@ -0,0 +1,79 @@ +{ + "excludeFiles": ["node_modules/**", "bower_components/**"], + + "requireCurlyBraces": [ + "if", + "else", + "for", + "while", + "do", + "try", + "catch" + ], + "requireOperatorBeforeLineBreak": true, + "requireCamelCaseOrUpperCaseIdentifiers": true, + "maximumLineLength": { + "value": 120, + "allowComments": true, + "allowRegex": true + }, + "validateIndentation": 2, + "validateQuoteMarks": "'", + + "disallowMultipleLineStrings": true, + "disallowMixedSpacesAndTabs": true, + "disallowTrailingWhitespace": true, + "disallowSpaceAfterPrefixUnaryOperators": true, + "disallowMultipleVarDecl": null, + + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do", + "switch", + "return", + "try", + "catch" + ], + "requireSpaceBeforeBinaryOperators": [ + "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", + "&=", "|=", "^=", "+=", + + "+", "-", "*", "/", "%", "<<", ">>", ">>>", "&", + "|", "^", "&&", "||", "===", "==", ">=", + "<=", "<", ">", "!=", "!==" + ], + "requireSpaceAfterBinaryOperators": true, + "requireSpacesInConditionalExpression": true, + "requireSpaceBeforeBlockStatements": true, + "requireLineFeedAtFileEnd": true, + "disallowSpacesInsideObjectBrackets": "all", + "disallowSpacesInsideArrayBrackets": "all", + "disallowSpacesInsideParentheses": true, + + "jsDoc": { + "checkAnnotations": { + "preset": "jsdoc3", + "extra": { + "ngdoc": true + } + }, + "checkParamNames": true, + "requireParamTypes": true, + "checkReturnTypes": true, + "checkTypes": true + }, + + "disallowMultipleLineBreaks": true, + + "disallowCommaBeforeLineBreak": null, + "disallowDanglingUnderscores": null, + "disallowEmptyBlocks": null, + "disallowTrailingComma": null, + "requireCommaBeforeLineBreak": null, + "requireDotNotation": null, + "requireMultipleVarDecl": null, + "requireParenthesesAroundIIFE": true +} diff --git a/gulp/gulp-my-tasks/tasks/.jshintrc b/gulp/gulp-my-tasks/tasks/.jshintrc new file mode 100644 index 0000000..2e382d2 --- /dev/null +++ b/gulp/gulp-my-tasks/tasks/.jshintrc @@ -0,0 +1,69 @@ +{ + "bitwise": true, + "camelcase": true, + "curly": true, + "eqeqeq": true, + "es3": false, + "forin": true, + "freeze": true, + "immed": true, + "indent": 2, + "latedef": "nofunc", + "newcap": true, + "noarg": true, + "noempty": true, + "nonbsp": true, + "nonew": true, + "plusplus": false, + "quotmark": "single", + "undef": true, + "unused": false, + "strict": false, + "maxparams": 10, + "maxdepth": 5, + "maxstatements": 40, + "maxcomplexity": 8, + "maxlen": 120, + + "asi": false, + "boss": false, + "debug": false, + "eqnull": true, + "esnext": false, + "evil": false, + "expr": false, + "funcscope": false, + "globalstrict": false, + "iterator": false, + "lastsemic": false, + "laxbreak": false, + "laxcomma": false, + "loopfunc": true, + "maxerr": 9999, + "moz": false, + "multistr": false, + "notypeof": false, + "proto": false, + "scripturl": false, + "shadow": false, + "sub": true, + "supernew": false, + "validthis": false, + "noyield": false, + + "browser": true, + "node": true, + + "globals": { + "angular": false, + /* Jasmine */ + "describe" : false, + "expect" : false, + "inject" : false, + "it" : false, + "before" : false, + "beforeEach" : false, + "after" : false, + "afterEach" : false + } +} diff --git a/gulp/gulp-my-tasks/tasks/favicon.ico b/gulp/gulp-my-tasks/tasks/favicon.ico new file mode 100644 index 0000000..b8e4f5f Binary files /dev/null and b/gulp/gulp-my-tasks/tasks/favicon.ico differ diff --git a/gulp/gulp-my-tasks/tasks/karma.conf.js b/gulp/gulp-my-tasks/tasks/karma.conf.js new file mode 100644 index 0000000..79914f5 --- /dev/null +++ b/gulp/gulp-my-tasks/tasks/karma.conf.js @@ -0,0 +1,105 @@ +// Karma configuration +// http://karma-runner.github.io/0.12/config/configuration-file.html +// Generated on 2015-08-16 using +// generator-karma 1.0.0 + +module.exports = function(config) { + 'use strict'; + + config.set({ + // enable / disable watching file and executing tests whenever any file changes + autoWatch: true, + + // base path, that will be used to resolve files and exclude + basePath: '', + + // testing framework to use (jasmine/mocha/qunit/...) + // as well as any additional frameworks (requirejs/chai/sinon/...) + frameworks: [ + 'jasmine' + ], + + // list of files / patterns to load in the browser + files: [ + //bower:js + //endbower + ], + + // list of files / patterns to exclude + exclude: [ + ], + + // web server port + port: 8080, + + // Start these browsers, currently available: + // - Chrome + // - ChromeCanary + // - Firefox + // - Opera + // - Safari (only Mac) + // - PhantomJS + // - IE (only Windows) + browsers: [ + 'PhantomJS' + ], + + // Which plugins to enable + plugins: [ + 'karma-phantomjs-launcher', + 'karma-jasmine', + 'karma-coverage', + 'karma-junit-reporter' + ], + + // command line argument override the configuration from the config file + reporters: ['progress', 'junit', 'coverage'], + + junitReporter: { + // results will be saved as $outputDir/$browserName.xml + outputDir: 'report', + // if included, results will be saved as $outputDir/$browserName/$outputFile + outputFile: 'test-results.xml' + // suite will become the package name attribute in xml testsuite element + // suite: '' + }, + + preprocessors: { + 'src/showcase/app/**/!(*.spec)+(.js)': ['coverage'] + }, + + coverageReporter: { + // specify a common output directory + dir: 'report/coverage', + reporters: [ + // reporters not supporting the `file` property + {type: 'html', subdir: 'report-html'}, + {type: 'lcov', subdir: 'report-lcov'}, + // reporters supporting the `file` property, use `subdir` to directly + // output them in the `dir` directory + {type: 'cobertura', subdir: '.', file: 'cobertura.txt'}, + {type: 'lcovonly', subdir: '.', file: 'report-lcovonly.txt'}, + {type: 'teamcity', subdir: '.', file: 'teamcity.txt'}, + {type: 'text', subdir: '.', file: 'text.txt'}, + {type: 'text-summary'} + ] + }, + + // Continuous Integration mode + // if true, it capture browsers, run tests and exit + singleRun: false, + + colors: true, + + // level of logging + // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG + logLevel: config.LOG_INFO + + // Uncomment the following lines if you are using grunt's server to run the tests + // proxies: { + // '/': 'http://localhost:9000/' + // }, + // URL root prevent conflicts with the site root + // urlRoot: '_karma_' + }); +}; diff --git a/gulp/gulp-my-tasks/tasks/server.config.js b/gulp/gulp-my-tasks/tasks/server.config.js new file mode 100644 index 0000000..7f9a2ad --- /dev/null +++ b/gulp/gulp-my-tasks/tasks/server.config.js @@ -0,0 +1,12 @@ +module.exports = function() { + var main = './src/showcase/'; + var config = { + main: main, + index: main + 'index.html', + port: 9000, + script: './server.js', + directory: './server/' + }; + + return config; +}; diff --git a/gulp/gulp-my-tasks/tasks/server.js b/gulp/gulp-my-tasks/tasks/server.js new file mode 100644 index 0000000..a0c3991 --- /dev/null +++ b/gulp/gulp-my-tasks/tasks/server.js @@ -0,0 +1,50 @@ +'use strict'; + +var currentDir = process.cwd(); +var express = require('express'); +var app = express(); +var favicon = require('serve-favicon'); +var logger = require('morgan'); +var port = 9000; +var environment = process.env.NODE_ENV; +var verbose = process.env.VERBOSE; + +app.use(favicon(__dirname + '/favicon.ico')); +if (verbose && verbose === true) { + app.use(logger('dev')); +} + +switch (environment) { + case 'production': + console.log('production mode'); + + app.use(express.static(currentDir + '/build/')); + + // Deep linking + app.use('/*', express.static(currentDir + '/build/index.html')); + break; + case 'ngdocs': + console.log('ngdocs mode'); + + app.use(express.static(currentDir + '/docs')); + + // Deep linking + app.use('/*', express.static(currentDir + '/docs')); + break; + default: + console.log('development mode'); + + app.use(express.static(currentDir + '/src/showcase/')); + app.use(express.static(currentDir + '/')); + + // Deep linking + app.use('/*', express.static(currentDir + '/src/showcase/index.html')); + break; +} + +app.listen(port, function() { + console.log('Express server listening on port ' + port); + console.log('env = ' + app.get('env') + + '\n __dirname = ' + __dirname + + '\n process.cwd = ' + currentDir); +}); diff --git a/gulp/gulp-my-tasks/tasks/tasks.config.js b/gulp/gulp-my-tasks/tasks/tasks.config.js new file mode 100644 index 0000000..8710931 --- /dev/null +++ b/gulp/gulp-my-tasks/tasks/tasks.config.js @@ -0,0 +1,99 @@ +module.exports = function() { + var main = './src/showcase/'; + var app = main + 'app/'; + var bower = { + json: require(process.cwd() + '/bower.json'), + directory: process.cwd() + '/bower_components/', + ignorePath: '../..' + }; + var $ = { + path: require('path') + }; + + return { + main: main, + jsAllFiles: [ + './src/**/*.js', + './*.js' + ], + jsFilesWithoutSpecs: [ + app + '**/*.module.js', + app + '**/*.js', + '!' + app + '**/*.spec.js' + ], + jsFilesStubs: [ + main + 'stubs/**/*.js' + ], + index: main + 'index.html', + jsHintConfigurationFile: $.path.join(__dirname, '.jshintrc'), + jscsConfigurationFile: $.path.join(__dirname, '.jscsrc'), + htmlHintConfigurationFile: $.path.join(__dirname, '.htmlhintrc'), + + karmaConf: 'karma.conf.js', + + build: { + directory: './build/' + }, + + html: app + '**/*.html', + templateFile: 'templates.js', + + temp: './.tmp/', + + /** + * wiredep options for index.html + */ + wiredepOptions: { + // The directory of your Bower packages. default: '.bowerrc'.directory || bower_components + bowerJson: bower.json, + // Your bower.json file contents. default: require('./bower.json') + directory: bower.directory, + // string or regexp to ignore from the injected filepath + ignorePath: bower.ignorePath, + dependencies: true, // default: true + onError: function(err) { + console.log('wiredep error: ' + err.code); + }, + onFileUpdated: function(filePath) { + console.log('wiredep updated file: ' + filePath); + }, + onPathInjected: function(fileObject) { + console.log('wiredep injected file: ' + fileObject.block); + console.log('wiredep injected file: ' + fileObject.file); + console.log('wiredep injected file: ' + fileObject.path); + }, + onMainNotFound: function(pkg) { + console.log('wiredep name of bower package without main: ' + pkg); + } + }, + + /** + * wiredep options for karma.conf.js + */ + wiredepKarmaOptions: { + // The directory of your Bower packages. default: '.bowerrc'.directory || bower_components + bowerJson: bower.json, + // Your bower.json file contents. default: require('./bower.json') + directory: bower.directory, + // string or regexp to ignore from the injected filepath + ignorePath: bower.ignorePath, + dependencies: true, // default: true + devDependencies: true, // default: false + onError: function(err) { + console.log('wiredep error: ' + err.code); + }, + onFileUpdated: function(filePath) { + console.log('wiredep updated file: ' + filePath); + }, + onPathInjected: function(fileObject) { + console.log('wiredep injected file: ' + fileObject.block); + console.log('wiredep injected file: ' + fileObject.file); + console.log('wiredep injected file: ' + fileObject.path); + }, + onMainNotFound: function(pkg) { + console.log('wiredep name of bower package without main: ' + pkg); + } + } + }; + +}; diff --git a/gulp/gulp-my-tasks/tasks/tasks.js b/gulp/gulp-my-tasks/tasks/tasks.js new file mode 100644 index 0000000..e1415e6 --- /dev/null +++ b/gulp/gulp-my-tasks/tasks/tasks.js @@ -0,0 +1,505 @@ +module.exports = function(gulp, customConfig) { + + var args = require('yargs').argv; + var extend = require('extend'); + var config = require('./tasks.config')(); + var del = require('del'); + var plugins = require('gulp-load-plugins')({lazy: true}); + var currentDir = process.cwd(); + var $ = { + path: require('path') + }; + + extend(true, config, customConfig); + + /** + * Arguments: + * + * [--verbose] : Various tasks will produce more output to the console. No verbose by default. + * [--stubs] : Using stubs in index.html (for mocking services, controllers or any other stuff) + * No stubs by default. + * [--environment production|development] : Running tasks in production or development environment. + * Development by default. + */ + + /** + * Default tasks + * + */ + gulp.task('help', plugins.taskListing); + gulp.task('default', ['help']); + + /** + * @ngdoc function + * + * @description + * vet (evaluate) the code and create coverage report. + * + * @returns {stream} + */ + gulp.task('vet', ['vet-js', 'vet-html']); + + /** + * @ngdoc function + * + * @description + * vet (evaluate) the JavaScript code and create coverage report. + * + * @returns {stream} + */ + gulp.task('vet-js', function() { + + log('*** Checking JavaScript source files with JSHint and JSCS ***'); + + return gulp.src(config.jsAllFiles) + .pipe(plugins.if(args.verbose, plugins.print())) + .pipe(plugins.jshint(config.jsHintConfigurationFile)) + .pipe(plugins.jshint.reporter('jshint-stylish', {verbose: true})) + .pipe(plugins.jshint.reporter('fail')) + .pipe(plugins.jscs({ + configPath: config.jscsConfigurationFile, + fix: false + })); + }); + + /** + * @ngdoc function + * + * @description + * vet (evaluate) the HTML code and create coverage report. + * + * @returns {stream} + */ + gulp.task('vet-html', function() { + + log('*** Checking HTML source files with HTMLHint ***'); + + return gulp.src(config.html) + .pipe(plugins.if(args.verbose, plugins.print())) + .pipe(plugins.htmlhint({htmlhintrc: config.htmlHintConfigurationFile})) + .pipe(plugins.htmlhint.failReporter()); + }); + + /** + * @ngdoc function + * + * @description + * wire up bower dependencies and inject files in index.html + * + * @returns {Stream} + */ + gulp.task('wireup', function() { + + log('*** Wiring bower dependencies and injecting files into html ***'); + + var wiredep = require('wiredep').stream; + var jsFiles = args.stubs ? [].concat(config.jsFilesWithoutSpecs, config.jsFilesStubs) : config.jsFilesWithoutSpecs; + + return gulp.src(config.index) + .pipe(wiredep(config.wiredepOptions)) + .pipe(inject(jsFiles, '')) + .pipe(gulp.dest(config.main)); + }); + + /** + * @ngdoc function + * + * @description + * Runs HTTP server. + */ + gulp.task('server', function(done) { + var environment = 'development'; + + if (args.environment) { + environment = args.environment; + } + + log('*** Starting server in ' + environment + ' mode ***'); + + server(environment); + done(); + }); + + /** + * @ngdoc function + * + * @description + * Runs specs once and exit. + * + * @returns {Stream} + */ + gulp.task('test', ['vet'], function(done) { + + log('*** Run tests once ***'); + + startTests(true, done); + }); + + /** + * @ngdoc function + * + * @description + * Run specs and wait. Watch for file changes and re-run tests on each change + */ + gulp.task('autotest', function(done) { + + log('*** Run tests and wait ***'); + + startTests(false, done); + }); + + /** + * @ngdoc function + * + * @description + * Builds application for production. + * + * @returns {stream} The stream. + */ + gulp.task('build', ['wireup', 'templatecache'], function() { + + log('*** Building application for production - Optimizing assets - HTML,CSS,JS ***'); + + var assets = plugins.useref.assets({searchPath: './'}); + // Filters are named for the gulp-useref path + var cssFilter = plugins.filter('**/*.css', {restore: true}); + var jsAppFilter = plugins.filter('**/app.min.js', {restore: true}); + var jslibFilter = plugins.filter('**/lib.min.js', {restore: true}); + var templateCache = config.temp + config.templateFile; + + return gulp.src(config.index) + + // Inject templates + .pipe(inject(templateCache, 'templates')) + + // Gather all assets from the html with useref + .pipe(assets) + + // Get the css + .pipe(cssFilter) + .pipe(plugins.if(args.verbose, plugins.bytediff.start())) + .pipe(plugins.minifyCss()) + .pipe(plugins.if(args.verbose, plugins.bytediff.stop(byteDiffFormat))) + .pipe(cssFilter.restore) + + // Get the custom javascript + .pipe(jsAppFilter) + .pipe(plugins.if(args.verbose, plugins.bytediff.start())) + .pipe(plugins.ngAnnotate({ + //jscs:disable + single_quotes: true, // jshint ignore:line + //jscs:enable + add: true + })) + .pipe(plugins.uglify({ + compress: { + //jscs:disable + drop_console: true, // jshint ignore:line + drop_debugger: true // jshint ignore:line + //jscs:enable + }, + output: { + //jscs:disable + quote_style: 3 // jshint ignore:line + //jscs:enable + } + })) + .pipe(plugins.if(args.verbose, plugins.bytediff.stop(byteDiffFormat))) + .pipe(getHeader()) + .pipe(jsAppFilter.restore) + + // Get the vendor javascript + .pipe(jslibFilter) + .pipe(plugins.if(args.verbose, plugins.bytediff.start())) + .pipe(plugins.uglify({ + output: { + //jscs:disable + quote_style: 3 // jshint ignore:line + //jscs:enable + } + })) + .pipe(plugins.if(args.verbose, plugins.bytediff.stop(byteDiffFormat))) + .pipe(jslibFilter.restore) + + // Take inventory of the file names for future rev numbers + .pipe(plugins.rev()) + + // Apply the concat and file replacement with useref + .pipe(assets.restore()) + .pipe(plugins.useref()) + + // Replace the file names in the html with rev numbers + .pipe(plugins.revReplace()) + + // Output to destination + .pipe(gulp.dest(config.build.directory)); + + /** + * @ngdoc function + * + * @description + * Format and return the header for files + * + * @returns {stream} The stream. + */ + function getHeader() { + var pkg = require($.path.join(process.cwd(), 'package.json')); + var banner = ['/**', + ' * <%= pkg.name %> - <%= pkg.description %>', + ' * @author <%= pkg.author.name %>', + ' * @email <%= pkg.author.email %>', + ' * @url <%= pkg.author.url %>', + ' * @version <%= pkg.version %>', + ' * @link <%= pkg.homepage %>', + ' * @license <%= pkg.license %>', + ' */', + '' + ].join('\n'); + return plugins.header(banner, {pkg: pkg}); + } + + }); + + /** + * @ngdoc function + * + * @description + * Cleans up files in distribution directory. + * + * @returns {undefined} + */ + gulp.task('clean', function(done) { + + log('*** Cleans up directories ***'); + + del.sync([config.build.directory + '**/*', config.temp]); + done(); + }); + + /** + * @ngdoc function + * + * @description + * Creates $templateCache from html templates + * + * @returns {stream} + */ + gulp.task('templatecache', ['clean'], function() { + + log('*** Creating AngularJS $templateCache ***'); + + return gulp + .src(config.html) + .pipe(plugins.if(args.verbose, plugins.bytediff.start())) + .pipe(plugins.minifyHtml({ + empty: true, + spare: true, + quotes: true + })) + .pipe(plugins.if(args.verbose, plugins.bytediff.stop(byteDiffFormat))) + .pipe(plugins.angularTemplatecache(config.templateFile, { + module: 'app.core', + root: 'app/', + standalone: false + } + )) + .pipe(gulp.dest(config.temp)); + }); + + /** + * @ngdoc function + * + * @description + * Generate documentation + * + * @returns {stream} + */ + gulp.task('ngdocs', function() { + var pkg = require($.path.join(process.cwd(), 'package.json')); + var gulpDocs = require('gulp-ngdocs'); + var options = { + html5Mode: true, + startPage: '/api/app', + title: pkg.description + }; + return gulpDocs.sections({ + api: { + glob:['src/**/*.js', '!src/**/*.spec.js'], + api: true, + title: 'API Documentation' + }}) + .pipe(gulpDocs.process(options)) + .pipe(gulp.dest('./docs')); + }); + + /** + * @ngdoc function + * + * @description + * Inject files in a sorted sequence at a specified inject label. + * + * @param {Array|string} source Source files (glob patterns) + * @param {string=} label The label name to be used by gulp-inject. + * @returns {stream} The stream. + */ + function inject(source, label) { + var options = {relative: false}; + if (label) { + options.name = 'inject:' + label; + } + + return plugins.inject( + gulp.src(source) + .pipe(plugins.angularFilesort()), options); + } + + /** + * @ngdoc function + * + * @description + * Runs HTTP server. + * + * @param {string=} [environment='development'] development or production environments. + * @returns {stream} The stream + */ + function server(environment) { + var nodeOptions = { + script: __dirname + '/server.js', + env: { + 'NODE_ENV': environment ? environment : 'development', + 'VERBOSE': args.verbose ? true : false + }, + verbose: args.verbose ? true : false, + watch: [__dirname + '/server.js'], + delay: 250 // 250ms + }; + + return plugins.nodemon(nodeOptions) + .on('restart', function(ev) { + log('HTTP server restarted'); + log('files changed:\n' + ev); + }) + .on('start', function () { + log('HTTP server started'); + synchronization(environment); + }) + .on('crash', function () { + log('HTTP server crashed'); + }) + .on('exit', function () { + log('HTTP server exited'); + }); + } + + /** + * @ngdoc function + * + * @description + * Tests runner, karma launcher. + * + * @param {boolean} singleRun True means run once and end (continuous integration), or keep running (development) + * @param {function} done Callback to fire when karma is done + * @returns {undefined} + */ + function startTests(singleRun, done) { + var wiredep = require('wiredep'); + var bowerFiles = wiredep(config.wiredepKarmaOptions)['js']; + var excludeFiles = []; + var Server = require('karma').Server; + var karma = new Server({ + files: [].concat( + bowerFiles, + process.cwd() + '/src/showcase/app/**/*.module.js', + process.cwd() + '/src/showcase/app/**/*.js' + ), + configFile: __dirname + '/karma.conf.js', + exclude: excludeFiles, + singleRun: singleRun + }, doneKarma); + + karma.start(); + + function doneKarma(result) { + log('Karma completed'); + log('Karma: tests exited with code ' + result); + done(); + } + } + + /** + * @ngdoc function + * + * @description + * Log messages to CLI. + * + * @param {string} message The message to be shown. + * @returns {undefined} + */ + function log(message) { + plugins.util.log(plugins.util.colors.blue(message)); + } + + /** + * @ngdoc function + * + * @description + * Format data generated by the gulp-bytediff plugin. + * + * @param {Object} data The data created by gulp-bytediff plugin. + * @returns {string} + */ + function byteDiffFormat(data) { + var difference = (data.savings > 0) ? ' smaller.' : ' larger.'; + return data.fileName + ' is ' + data.percent + '%' + difference; + } + + /** + * @ngdoc function + * + * @description + * Files synchronization. + * + * @param {string=} [environment='development'] development or production environments. + * @returns {undefined} + */ + function synchronization(environment) { + + log('Files synchronization'); + + var jsFiles = args.stubs ? [].concat(config.jsFilesWithoutSpecs, config.jsFilesStubs) : config.jsFilesWithoutSpecs; + + switch (environment) { + case 'production': + jsFiles = jsFiles.concat(config.html); + plugins.watch(jsFiles, { + name: 'Files synchronization', + verbose: true, + readDelay: 250 + }, plugins.batch(function (events, done) { + // TODO: gulp.start going to be deprecated in gulp 4.0.0 version. Alternatives? + gulp.start('build', done); + })); + break; + case 'ngdocs': + plugins.watch(jsFiles, { + name: 'Files synchronization', + verbose: true, + readDelay: 250 + }, plugins.batch(function (events, done) { + // TODO: gulp.start going to be deprecated in gulp 4.0.0 version. Alternatives? + gulp.start('ngdocs', done); + })); + break; + default: + plugins.watch(jsFiles, { + name: 'Files synchronization', + verbose: true, + readDelay: 250 + }, plugins.batch(function (events, done) { + // TODO: gulp.start going to be deprecated in gulp 4.0.0 version. Alternatives? + gulp.start('wireup', done); + })); + break; + } + } +};