pax_global_header00006660000000000000000000000064126561612450014522gustar00rootroot0000000000000052 comment=9c14e3a13a73a32e424f144d62566671b2fcdbed gulp-3.9.1/000077500000000000000000000000001265616124500125035ustar00rootroot00000000000000gulp-3.9.1/.editorconfig000066400000000000000000000003171265616124500151610ustar00rootroot00000000000000# editorconfig.org root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false gulp-3.9.1/.eslintrc000066400000000000000000000000301265616124500143200ustar00rootroot00000000000000{ "extends": "gulp" } gulp-3.9.1/.gitignore000066400000000000000000000001771265616124500145000ustar00rootroot00000000000000.DS_Store *.log node_modules build *.node components coverage *.orig .idea sandbox test/out-fixtures/* test/watch-*.txt gulp.1 gulp-3.9.1/.jscsrc000066400000000000000000000000301265616124500137640ustar00rootroot00000000000000{ "preset": "gulp", } gulp-3.9.1/.npmignore000066400000000000000000000001701265616124500145000ustar00rootroot00000000000000.DS_Store *.log node_modules build *.node components coverage *.orig .idea sandbox test/out-fixtures/* test/watch-*.txt gulp-3.9.1/.travis.yml000066400000000000000000000002071265616124500146130ustar00rootroot00000000000000sudo: false language: node_js node_js: - "0.10" - "0.12" - "4" - "stable" after_script: - npm run coveralls git: depth: 10 gulp-3.9.1/CHANGELOG.md000066400000000000000000000131221265616124500143130ustar00rootroot00000000000000# gulp changelog ## 3.9.0 - add babel support - add transpiler fallback support - add support for some renamed transpilers (livescript, etc) - add JSCS - update dependecies (liftoff, interpret) - documentation tweaks ## 3.8.11 - fix node 0.12/iojs problems - add node 0.12 and iojs to travis - update dependencies (liftoff, v8flags) - documentation tweaks ## 3.8.10 - add link to spanish docs - update dependencies (archy, semver, mocha, etc) - documentation tweaks ## 3.8.9 - fix local version undefined output - add completion for fish shell - fix powershell completion line splitting - add support for arbitrary node flags (oops, should have been a minor bump) - add v8flags dependency - update dependencies (liftoff) - documentation tweaks ## 3.8.8 - update dependencies (minimist, tildify) - documentation tweaks ## 3.8.7 - handle errors a bit better - update dependencies (gulp-util, semver, etc) - documentation tweaks ## 3.8.6 - remove executable flag from LICENSE - update dependencies (chalk, minimist, liftoff, etc) - documentation tweaks ## 3.8.5 - simplify --silent and --tasks-simple - fix bug in autocomplete where errors would come out ## 3.8.4 - CLI will use exit code 1 on exit when any task fails during the lifetime of the process ## 3.8.3 - Tweak error formatting to work better with PluginErrors and strings ## 3.8.2 - add manpage generation ## 3.8.1 - the CLI now adds process.env.INIT_CWD which is the original cwd it was launched from ## 3.8.0 - update vinyl-fs - gulp.src is now a writable passthrough, this means you can use it to add files to your pipeline at any point - gulp.dest can now take a function to determine the folder This is now possible! ```js gulp.src('lib/*.js') .pipe(uglify()) .pipe(gulp.src('styles/*.css')) .pipe(gulp.dest(function(file){ // I don't know, you can do something cool here return 'build/whatever'; })); ``` ## 3.7.0 - update vinyl-fs to remove BOM from UTF8 files - add --tasks-simple flag for plaintext task listings - updated autocomplete scripts to be simpler and use new --tasks-simple flag - added support for transpilers via liftoff 0.11 and interpret - just npm install your compiler (coffee-script for example) and it will work out of the box ## 3.5.5 - update deps - gulp.dest now support mode option, uses source file mode by default (file.stat.mode) - use chalk for colors in bin - update gulp.env deprecation msg to be more helpful ## 3.5.2 - add -V for version on CLI (unix standard) - -v is deprecated, use -V - add -T as an alias for --tasks - documentation ## 3.5 - added `gulp.watch(globs, tasksArray)` sugar - remove gulp.taskQueue - deprecate gulp.run - deprecate gulp.env - add engineStrict to prevent people with node < 0.9 from installing ## 3.4 - added `--tasks` that prints out the tree of tasks + deps - global cli + local install mismatch is no longer fatal - remove tests for fs stuff - switch core src, dest, and watch to vinyl-fs - internal cleaning ## 3.3.4 - `--base` is now `--cwd` ## 3.3.3 - support for `--base` CLI arg to change where the search for gulpfile/`--require`s starts - support for `--gulpfile` CLI arg to point to a gulpfile specifically ## 3.3.0 - file.contents streams are no longer paused coming out of src - dest now passes files through before they are empty to fix passing to multiple dests ## 3.2.4 - Bug fix - we didn't have any CLI tests ## 3.2.3 - Update dependencies for bug fixes - autocomplete stuff in the completion folder ## 3.2 - File object is now [vinyl](https://github.com/wearefractal/vinyl) - .watch() is now [glob-watcher](https://github.com/wearefractal/glob-watcher) - Fix CLI -v when no gulpfile found - gulp-util updated - Logging moved to CLI bin file - Will cause double logging if you update global CLI to 3.2 but not local - Will cause no logging if you update local to 3.1 but not global CLI - Drop support for < 0.9 ## 3.1.3 - Move isStream and isBuffer to gulp-util ## 3.1 - Move file class to gulp-util ## 3.0 - Ability to pass multiple globs and glob negations to glob-stream - Breaking change to the way glob-stream works - File object is now a class - file.shortened changed to file.relative - file.cwd added - Break out getStats to avoid nesting - Major code reorganization ## 2.7 - Breaking change to the way options are passed to glob-stream - Introduce new File object to ease pain of computing shortened names (now a getter) ## 2.4 - 2.6 - Moved stuff to gulp-util - Quit exposing createGlobStream (just use the glob-stream module) - More logging - Prettier time durations - Tons of documentation changes - gulp.trigger(tasks...) as a through stream ## 1.2-2.4 (11/12/13) - src buffer=false fixed for 0.8 and 0.9 (remember to .resume() on these versions before consuming) - CLI completely rewritten - Colorful logging - Uses local version of gulp to run tasks - Uses findup to locate gulpfile (so you can run it anywhere in your project) - chdir to gulpfile directory before loading it - Correct exit codes on errors - silent flag added to gulp to disable logging - Fixes to task orchestration (3rd party) - Better support for globbed directories (thanks @robrich) ## 1.2 (10/28/13) - Can specify buffer=false on src streams to make file.content a stream - Can specify read=false on src streams to disable file.content ## 1.1 (10/21/13) - Can specify run callback - Can specify task dependencies - Tasks can accept callback or return promise - `gulp.verbose` exposes run-time internals ## 1.0 (9/26/13) - Specify dependency versions - Updated docs ## 0.2 (8/6/13) - Rename .files() to .src() and .folder() to .dest() ## 0.1 (7/18/13) - Initial Release gulp-3.9.1/CONTRIBUTING.md000066400000000000000000000071641265616124500147440ustar00rootroot00000000000000# Request for contributions Please contribute to this repository if any of the following is true: - You have expertise in community development, communication, or education - You want open source communities to be more collaborative and inclusive - You want to help lower the burden to first time contributors # How to contribute Prerequisites: - familiarity with [GitHub PRs](https://help.github.com/articles/using-pull-requests) (pull requests) and issues - knowledge of Markdown for editing `.md` documents In particular, this community seeks the following types of contributions: - ideas: participate in an Issues thread or start your own to have your voice heard - resources: submit a PR to add to [docs README.md](/docs/README.md) with links to related content - outline sections: help us ensure that this repository is comprehensive. If there is a topic that is overlooked, please add it, even if it is just a stub in the form of a header and single sentence. Initially, most things fall into this category - write: contribute your expertise in an area by helping us expand the included content - copy editing: fix typos, clarify language, and generally improve the quality of the content - formatting: help keep content easy to read with consistent formatting - code: Fix issues or contribute new features to this or any related projects # Conduct We are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, disability, ethnicity, religion, or similar personal characteristic. On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all. Please be kind and courteous. There's no need to be mean or rude. Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer, merely an optimal answer given a set of values and circumstances. Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [gulpjs](https://github.com/orgs/gulpjs/people) core team immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome. # Communication There is an IRC channel on irc.freenode.net, channel `#gulpjs`. You're welcome to drop in and ask questions, discuss bugs and such. The channel is not currently logged. GitHub issues are the primary way for communicating about specific proposed changes to this project. In both contexts, please follow the conduct guidelines above. Language issues are often contentious and we'd like to keep discussion brief, civil and focused on what we're actually doing, not wandering off into too much imaginary stuff. # Frequently Asked Questions See [the FAQ docs page](/docs/FAQ.md) gulp-3.9.1/LICENSE000066400000000000000000000021221265616124500135050ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2013-2016 Fractal Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. gulp-3.9.1/README.md000066400000000000000000000075701265616124500137730ustar00rootroot00000000000000

The streaming build system

[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![Gitter chat][gitter-image]][gitter-url] ## What is gulp? - **Automation** - gulp is a toolkit that helps you automate painful or time-consuming tasks in your development workflow. - **Platform-agnostic** - Integrations are built into all major IDEs and people are using gulp with PHP, .NET, Node.js, Java, and other platforms. - **Strong Ecosystem** - Use npm modules to do anything you want + over 2000 curated plugins for streaming file transformations - **Simple** - By providing only a minimal API surface, gulp is easy to learn and simple to use ## Documentation For a Getting started guide, API docs, recipes, making a plugin, etc. check out or docs! - Need something reliable? Check out the [documentation for the current release](/docs/README.md)! - Want to help us test the latest and greatest? Check out the [documentation for the next release](https://github.com/gulpjs/gulp/tree/4.0)! ## Sample `gulpfile.js` This file will give you a taste of what gulp does. ```js var gulp = require('gulp'); var coffee = require('gulp-coffee'); var concat = require('gulp-concat'); var uglify = require('gulp-uglify'); var imagemin = require('gulp-imagemin'); var sourcemaps = require('gulp-sourcemaps'); var del = require('del'); var paths = { scripts: ['client/js/**/*.coffee', '!client/external/**/*.coffee'], images: 'client/img/**/*' }; // Not all tasks need to use streams // A gulpfile is just another node program and you can use any package available on npm gulp.task('clean', function() { // You can use multiple globbing patterns as you would with `gulp.src` return del(['build']); }); gulp.task('scripts', ['clean'], function() { // Minify and copy all JavaScript (except vendor scripts) // with sourcemaps all the way down return gulp.src(paths.scripts) .pipe(sourcemaps.init()) .pipe(coffee()) .pipe(uglify()) .pipe(concat('all.min.js')) .pipe(sourcemaps.write()) .pipe(gulp.dest('build/js')); }); // Copy all static images gulp.task('images', ['clean'], function() { return gulp.src(paths.images) // Pass in options to the task .pipe(imagemin({optimizationLevel: 5})) .pipe(gulp.dest('build/img')); }); // Rerun the task when a file changes gulp.task('watch', function() { gulp.watch(paths.scripts, ['scripts']); gulp.watch(paths.images, ['images']); }); // The default task (called when you run `gulp` from cli) gulp.task('default', ['watch', 'scripts', 'images']); ``` ## Incremental Builds We recommend these plugins: - [gulp-changed](https://github.com/sindresorhus/gulp-changed) - only pass through changed files - [gulp-cached](https://github.com/contra/gulp-cached) - in-memory file cache, not for operation on sets of files - [gulp-remember](https://github.com/ahaurw01/gulp-remember) - pairs nicely with gulp-cached - [gulp-newer](https://github.com/tschaub/gulp-newer) - pass through newer source files only, supports many:1 source:dest ## Want to contribute? Anyone can help make this project better - check out our [Contributing guide](/CONTRIBUTING.md)! [downloads-image]: https://img.shields.io/npm/dm/gulp.svg [npm-url]: https://www.npmjs.com/package/gulp [npm-image]: https://img.shields.io/npm/v/gulp.svg [travis-url]: https://travis-ci.org/gulpjs/gulp [travis-image]: https://img.shields.io/travis/gulpjs/gulp.svg [coveralls-url]: https://coveralls.io/r/gulpjs/gulp [coveralls-image]: https://img.shields.io/coveralls/gulpjs/gulp/master.svg [gitter-url]: https://gitter.im/gulpjs/gulp [gitter-image]: https://badges.gitter.im/gulpjs/gulp.png gulp-3.9.1/bin/000077500000000000000000000000001265616124500132535ustar00rootroot00000000000000gulp-3.9.1/bin/gulp.js000077500000000000000000000124101265616124500145610ustar00rootroot00000000000000#!/usr/bin/env node 'use strict'; var gutil = require('gulp-util'); var prettyTime = require('pretty-hrtime'); var chalk = require('chalk'); var semver = require('semver'); var archy = require('archy'); var Liftoff = require('liftoff'); var tildify = require('tildify'); var interpret = require('interpret'); var v8flags = require('v8flags'); var completion = require('../lib/completion'); var argv = require('minimist')(process.argv.slice(2)); var taskTree = require('../lib/taskTree'); // Set env var for ORIGINAL cwd // before anything touches it process.env.INIT_CWD = process.cwd(); var cli = new Liftoff({ name: 'gulp', completions: completion, extensions: interpret.jsVariants, v8flags: v8flags, }); // Exit with 0 or 1 var failed = false; process.once('exit', function(code) { if (code === 0 && failed) { process.exit(1); } }); // Parse those args m8 var cliPackage = require('../package'); var versionFlag = argv.v || argv.version; var tasksFlag = argv.T || argv.tasks; var tasks = argv._; var toRun = tasks.length ? tasks : ['default']; // This is a hold-over until we have a better logging system // with log levels var simpleTasksFlag = argv['tasks-simple']; var shouldLog = !argv.silent && !simpleTasksFlag; if (!shouldLog) { gutil.log = function() {}; } cli.on('require', function(name) { gutil.log('Requiring external module', chalk.magenta(name)); }); cli.on('requireFail', function(name) { gutil.log(chalk.red('Failed to load external module'), chalk.magenta(name)); }); cli.on('respawn', function(flags, child) { var nodeFlags = chalk.magenta(flags.join(', ')); var pid = chalk.magenta(child.pid); gutil.log('Node flags detected:', nodeFlags); gutil.log('Respawned to PID:', pid); }); cli.launch({ cwd: argv.cwd, configPath: argv.gulpfile, require: argv.require, completion: argv.completion, }, handleArguments); // The actual logic function handleArguments(env) { if (versionFlag && tasks.length === 0) { gutil.log('CLI version', cliPackage.version); if (env.modulePackage && typeof env.modulePackage.version !== 'undefined') { gutil.log('Local version', env.modulePackage.version); } process.exit(0); } if (!env.modulePath) { gutil.log( chalk.red('Local gulp not found in'), chalk.magenta(tildify(env.cwd)) ); gutil.log(chalk.red('Try running: npm install gulp')); process.exit(1); } if (!env.configPath) { gutil.log(chalk.red('No gulpfile found')); process.exit(1); } // Check for semver difference between cli and local installation if (semver.gt(cliPackage.version, env.modulePackage.version)) { gutil.log(chalk.red('Warning: gulp version mismatch:')); gutil.log(chalk.red('Global gulp is', cliPackage.version)); gutil.log(chalk.red('Local gulp is', env.modulePackage.version)); } // Chdir before requiring gulpfile to make sure // we let them chdir as needed if (process.cwd() !== env.cwd) { process.chdir(env.cwd); gutil.log( 'Working directory changed to', chalk.magenta(tildify(env.cwd)) ); } // This is what actually loads up the gulpfile require(env.configPath); gutil.log('Using gulpfile', chalk.magenta(tildify(env.configPath))); var gulpInst = require(env.modulePath); logEvents(gulpInst); process.nextTick(function() { if (simpleTasksFlag) { return logTasksSimple(env, gulpInst); } if (tasksFlag) { return logTasks(env, gulpInst); } gulpInst.start.apply(gulpInst, toRun); }); } function logTasks(env, localGulp) { var tree = taskTree(localGulp.tasks); tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath)); archy(tree) .split('\n') .forEach(function(v) { if (v.trim().length === 0) { return; } gutil.log(v); }); } function logTasksSimple(env, localGulp) { console.log(Object.keys(localGulp.tasks) .join('\n') .trim()); } // Format orchestrator errors function formatError(e) { if (!e.err) { return e.message; } // PluginError if (typeof e.err.showStack === 'boolean') { return e.err.toString(); } // Normal error if (e.err.stack) { return e.err.stack; } // Unknown (string, number, etc.) return new Error(String(e.err)).stack; } // Wire up logging events function logEvents(gulpInst) { // Total hack due to poor error management in orchestrator gulpInst.on('err', function() { failed = true; }); gulpInst.on('task_start', function(e) { // TODO: batch these // so when 5 tasks start at once it only logs one time with all 5 gutil.log('Starting', '\'' + chalk.cyan(e.task) + '\'...'); }); gulpInst.on('task_stop', function(e) { var time = prettyTime(e.hrDuration); gutil.log( 'Finished', '\'' + chalk.cyan(e.task) + '\'', 'after', chalk.magenta(time) ); }); gulpInst.on('task_err', function(e) { var msg = formatError(e); var time = prettyTime(e.hrDuration); gutil.log( '\'' + chalk.cyan(e.task) + '\'', chalk.red('errored after'), chalk.magenta(time) ); gutil.log(msg); }); gulpInst.on('task_not_found', function(err) { gutil.log( chalk.red('Task \'' + err.task + '\' is not in your gulpfile') ); gutil.log('Please check the documentation for proper gulpfile formatting'); process.exit(1); }); } gulp-3.9.1/completion/000077500000000000000000000000001265616124500146545ustar00rootroot00000000000000gulp-3.9.1/completion/README.md000066400000000000000000000010001265616124500161220ustar00rootroot00000000000000# Completion for gulp > Thanks to grunt team and Tyler Kellen To enable tasks auto-completion in shell you should add `eval "$(gulp --completion=shell)"` in your `.shellrc` file. ## Bash Add `eval "$(gulp --completion=bash)"` to `~/.bashrc`. ## Zsh Add `eval "$(gulp --completion=zsh)"` to `~/.zshrc`. ## Powershell Add `Invoke-Expression ((gulp --completion=powershell) -join [System.Environment]::NewLine)` to `$PROFILE`. ## Fish Add `gulp --completion=fish | source` to `~/.config/fish/config.fish`. gulp-3.9.1/completion/bash000066400000000000000000000013361265616124500155170ustar00rootroot00000000000000#!/bin/bash # Borrowed from grunt-cli # http://gruntjs.com/ # # Copyright (c) 2012 Tyler Kellen, contributors # Licensed under the MIT license. # https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT # Usage: # # To enable bash completion for gulp, add the following line (minus the # leading #, which is the bash comment character) to your ~/.bashrc file: # # eval "$(gulp --completion=bash)" # Enable bash autocompletion. function _gulp_completions() { # The currently-being-completed word. local cur="${COMP_WORDS[COMP_CWORD]}" #Grab tasks local compls=$(gulp --tasks-simple) # Tell complete what stuff to show. COMPREPLY=($(compgen -W "$compls" -- "$cur")) } complete -o default -F _gulp_completions gulp gulp-3.9.1/completion/fish000066400000000000000000000003421265616124500155270ustar00rootroot00000000000000#!/usr/bin/env fish # Usage: # # To enable fish completion for gulp, add the following line to # your ~/.config/fish/config.fish file: # # gulp --completion=fish | source complete -c gulp -a "(gulp --tasks-simple)" -f gulp-3.9.1/completion/powershell000066400000000000000000000036001265616124500167620ustar00rootroot00000000000000# Copyright (c) 2014 Jason Jarrett # # Tab completion for the `gulp` # # Usage: # # To enable powershell completion for gulp you need to be running # at least PowerShell v3 or greater and add the below to your $PROFILE # # Invoke-Expression ((gulp --completion=powershell) -join [System.Environment]::NewLine) # # $gulp_completion_Process = { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) # Load up an assembly to read the gulpfile's sha1 if(-not $global:GulpSHA1Managed) { [Reflection.Assembly]::LoadWithPartialName("System.Security") | out-null $global:GulpSHA1Managed = new-Object System.Security.Cryptography.SHA1Managed } # setup a global (in-memory) cache if(-not $global:GulpfileShaCache) { $global:GulpfileShaCache = @{}; } $cache = $global:GulpfileShaCache; # Get the gulpfile's sha1 $sha1gulpFile = (resolve-path gulpfile.js -ErrorAction Ignore | %{ $file = [System.IO.File]::Open($_.Path, "open", "read") [string]::join('', ($global:GulpSHA1Managed.ComputeHash($file) | %{ $_.ToString("x2") })) $file.Dispose() }) # lookup the sha1 for previously cached task lists. if($cache.ContainsKey($sha1gulpFile)){ $tasks = $cache[$sha1gulpFile]; } else { $tasks = (gulp --tasks-simple).split("`n"); $cache[$sha1gulpFile] = $tasks; } $tasks | where { $_.startswith($commandName) } Sort-Object | foreach { New-Object System.Management.Automation.CompletionResult $_, $_, 'ParameterValue', ('{0}' -f $_) } } if (-not $global:options) { $global:options = @{ CustomArgumentCompleters = @{}; NativeArgumentCompleters = @{} } } $global:options['NativeArgumentCompleters']['gulp'] = $gulp_completion_Process $function:tabexpansion2 = $function:tabexpansion2 -replace 'End\r\n{','End { if ($null -ne $options) { $options += $global:options} else {$options = $global:options}' gulp-3.9.1/completion/zsh000066400000000000000000000011211265616124500153760ustar00rootroot00000000000000#!/bin/zsh # Borrowed from grunt-cli # http://gruntjs.com/ # # Copyright (c) 2012 Tyler Kellen, contributors # Licensed under the MIT license. # https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT # Usage: # # To enable zsh completion for gulp, add the following line (minus the # leading #, which is the zsh comment character) to your ~/.zshrc file: # # eval "$(gulp --completion=zsh)" # Enable zsh autocompletion. function _gulp_completion() { # Grab tasks compls=$(gulp --tasks-simple) completions=(${=compls}) compadd -- $completions } compdef _gulp_completion gulp gulp-3.9.1/docs/000077500000000000000000000000001265616124500134335ustar00rootroot00000000000000gulp-3.9.1/docs/API.md000066400000000000000000000205531265616124500143730ustar00rootroot00000000000000## gulp API docs Jump to: [gulp.src](#gulpsrcglobs-options) | [gulp.dest](#gulpdestpath-options) | [gulp.task](#gulptaskname--deps-fn) | [gulp.watch](#gulpwatchglob--opts-tasks-or-gulpwatchglob--opts-cb) ### gulp.src(globs[, options]) Emits files matching provided glob or an array of globs. Returns a [stream](http://nodejs.org/api/stream.html) of [Vinyl files](https://github.com/wearefractal/vinyl-fs) that can be [piped](http://nodejs.org/api/stream.html#stream_readable_pipe_destination_options) to plugins. ```javascript gulp.src('client/templates/*.jade') .pipe(jade()) .pipe(minify()) .pipe(gulp.dest('build/minified_templates')); ``` #### globs Type: `String` or `Array` Glob or array of globs to read. Globs use [node-glob syntax] except that negation is fully supported. A glob that begins with `!` excludes matching files from the glob results up to that point. For example, consider this directory structure: client/ a.js bob.js bad.js The following expression matches `a.js` and `bad.js`: gulp.src(['client/*.js', '!client/b*.js', 'client/bad.js']) #### options Type: `Object` Options to pass to [node-glob] through [glob-stream]. gulp supports all [options supported by node-glob][node-glob documentation] and [glob-stream] except `ignore` and adds the following options. ##### options.buffer Type: `Boolean` Default: `true` Setting this to `false` will return `file.contents` as a stream and not buffer files. This is useful when working with large files. **Note:** Plugins might not implement support for streams. ##### options.read Type: `Boolean` Default: `true` Setting this to `false` will return `file.contents` as null and not read the file at all. ##### options.base Type: `String` Default: everything before a glob starts (see [glob2base]) E.g., consider `somefile.js` in `client/js/somedir`: ```js gulp.src('client/js/**/*.js') // Matches 'client/js/somedir/somefile.js' and resolves `base` to `client/js/` .pipe(minify()) .pipe(gulp.dest('build')); // Writes 'build/somedir/somefile.js' gulp.src('client/js/**/*.js', { base: 'client' }) .pipe(minify()) .pipe(gulp.dest('build')); // Writes 'build/js/somedir/somefile.js' ``` ### gulp.dest(path[, options]) Can be piped to and it will write files. Re-emits all data passed to it so you can pipe to multiple folders. Folders that don't exist will be created. ```javascript gulp.src('./client/templates/*.jade') .pipe(jade()) .pipe(gulp.dest('./build/templates')) .pipe(minify()) .pipe(gulp.dest('./build/minified_templates')); ``` The write path is calculated by appending the file relative path to the given destination directory. In turn, relative paths are calculated against the file base. See `gulp.src` above for more info. #### path Type: `String` or `Function` The path (output folder) to write files to. Or a function that returns it, the function will be provided a [vinyl File instance](https://github.com/wearefractal/vinyl). #### options Type: `Object` ##### options.cwd Type: `String` Default: `process.cwd()` `cwd` for the output folder, only has an effect if provided output folder is relative. ##### options.mode Type: `String` Default: `0777` Octal permission string specifying mode for any folders that need to be created for output folder. ### gulp.task(name [, deps, fn]) Define a task using [Orchestrator]. ```js gulp.task('somename', function() { // Do stuff }); ``` #### name Type: `String` The name of the task. Tasks that you want to run from the command line should not have spaces in them. #### deps Type: `Array` An array of tasks to be executed and completed before your task will run. ```js gulp.task('mytask', ['array', 'of', 'task', 'names'], function() { // Do stuff }); ``` **Note:** Are your tasks running before the dependencies are complete? Make sure your dependency tasks are correctly using the async run hints: take in a callback or return a promise or event stream. You can also omit the function if you only want to run a bundle of dependency tasks: ```js gulp.task('build', ['array', 'of', 'task', 'names']); ``` **Note:** The tasks will run in parallel (all at once), so don't assume that the tasks will start/finish in order. #### fn Type: `Function` The function performs the task's main operations. Generally this takes the form of: ```js gulp.task('buildStuff', function() { // Do something that "builds stuff" var stream = gulp.src(/*some source path*/) .pipe(somePlugin()) .pipe(someOtherPlugin()) .pipe(gulp.dest(/*some destination*/)); return stream; }); ``` #### Async task support Tasks can be made asynchronous if its `fn` does one of the following: ##### Accept a callback ```javascript // run a command in a shell var exec = require('child_process').exec; gulp.task('jekyll', function(cb) { // build Jekyll exec('jekyll build', function(err) { if (err) return cb(err); // return error cb(); // finished task }); }); ``` ##### Return a stream ```js gulp.task('somename', function() { var stream = gulp.src('client/**/*.js') .pipe(minify()) .pipe(gulp.dest('build')); return stream; }); ``` ##### Return a promise ```javascript var Q = require('q'); gulp.task('somename', function() { var deferred = Q.defer(); // do async stuff setTimeout(function() { deferred.resolve(); }, 1); return deferred.promise; }); ``` **Note:** By default, tasks run with maximum concurrency -- e.g. it launches all the tasks at once and waits for nothing. If you want to create a series where tasks run in a particular order, you need to do two things: - give it a hint to tell it when the task is done, - and give it a hint that a task depends on completion of another. For these examples, let's presume you have two tasks, "one" and "two" that you specifically want to run in this order: 1. In task "one" you add a hint to tell it when the task is done. Either take in a callback and call it when you're done or return a promise or stream that the engine should wait to resolve or end respectively. 2. In task "two" you add a hint telling the engine that it depends on completion of the first task. So this example would look like this: ```js var gulp = require('gulp'); // takes in a callback so the engine knows when it'll be done gulp.task('one', function(cb) { // do stuff -- async or otherwise cb(err); // if err is not null and not undefined, the run will stop, and note that it failed }); // identifies a dependent task must be complete before this one begins gulp.task('two', ['one'], function() { // task 'one' is done now }); gulp.task('default', ['one', 'two']); ``` ### gulp.watch(glob [, opts], tasks) or gulp.watch(glob [, opts, cb]) Watch files and do something when a file changes. This always returns an EventEmitter that emits `change` events. ### gulp.watch(glob[, opts], tasks) #### glob Type: `String` or `Array` A single glob or array of globs that indicate which files to watch for changes. #### opts Type: `Object` Options, that are passed to [`gaze`](https://github.com/shama/gaze). #### tasks Type: `Array` Names of task(s) to run when a file changes, added with `gulp.task()` ```js var watcher = gulp.watch('js/**/*.js', ['uglify','reload']); watcher.on('change', function(event) { console.log('File ' + event.path + ' was ' + event.type + ', running tasks...'); }); ``` ### gulp.watch(glob[, opts, cb]) #### glob Type: `String` or `Array` A single glob or array of globs that indicate which files to watch for changes. #### opts Type: `Object` Options, that are passed to [`gaze`](https://github.com/shama/gaze). #### cb(event) Type: `Function` Callback to be called on each change. ```js gulp.watch('js/**/*.js', function(event) { console.log('File ' + event.path + ' was ' + event.type + ', running tasks...'); }); ``` The callback will be passed an object, `event`, that describes the change: ##### event.type Type: `String` The type of change that occurred, either `added`, `changed` or `deleted`. ##### event.path Type: `String` The path to the file that triggered the event. [node-glob]: https://github.com/isaacs/node-glob [node-glob documentation]: https://github.com/isaacs/node-glob#options [node-glob syntax]: https://github.com/isaacs/node-glob [glob-stream]: https://github.com/wearefractal/glob-stream [gulp-if]: https://github.com/robrich/gulp-if [Orchestrator]: https://github.com/robrich/orchestrator [glob2base]: https://github.com/wearefractal/glob2base gulp-3.9.1/docs/CLI.md000066400000000000000000000034051265616124500143660ustar00rootroot00000000000000## gulp CLI docs ### Flags gulp has very few flags to know about. All other flags are for tasks to use if needed. - `-v` or `--version` will display the global and local gulp versions - `--require ` will require a module before running the gulpfile. This is useful for transpilers but also has other applications. You can use multiple `--require` flags - `--gulpfile ` will manually set path of gulpfile. Useful if you have multiple gulpfiles. This will set the CWD to the gulpfile directory as well - `--cwd ` will manually set the CWD. The search for the gulpfile, as well as the relativity of all requires will be from here - `-T` or `--tasks` will display the task dependency tree for the loaded gulpfile - `--tasks-simple` will display a plaintext list of tasks for the loaded gulpfile - `--color` will force gulp and gulp plugins to display colors even when no color support is detected - `--no-color` will force gulp and gulp plugins to not display colors even when color support is detected - `--silent` will disable all gulp logging The CLI adds process.env.INIT_CWD which is the original cwd it was launched from. #### Task specific flags Refer to this [StackOverflow](http://stackoverflow.com/questions/23023650/is-it-possible-to-pass-a-flag-to-gulp-to-have-it-run-tasks-in-different-ways) link for how to add task specific flags ### Tasks Tasks can be executed by running `gulp `. Just running `gulp` will execute the task you registered called `default`. If there is no `default` task gulp will error. ### Compilers You can find a list of supported languages at [interpret](https://github.com/tkellen/node-interpret#jsvariants). If you would like to add support for a new language send pull request/open issues there. gulp-3.9.1/docs/FAQ.md000066400000000000000000000033571265616124500143740ustar00rootroot00000000000000# FAQ ## Why gulp? Why not ____? See the [gulp introduction slideshow] for a rundown on how gulp came to be. ## Is it "gulp" or "Gulp"? gulp is always lowercase. The only exception is in the gulp logo where gulp is capitalized. ## Where can I find a list of gulp plugins? gulp plugins always include the `gulpplugin` keyword. [Search gulp plugins][search-gulp-plugins] or [view all plugins][npm plugin search]. ## I want to write a gulp plugin, how do I get started? See the [Writing a gulp plugin] wiki page for guidelines and an example to get you started. ## My plugin does ____, is it doing too much? Probably. Ask yourself: 1. Is my plugin doing something that other plugins may need to do? - If so, that piece of functionality should be a separate plugin. [Check if it already exists on npm][npm plugin search]. 1. Is my plugin doing two, completely different things based on a configuration option? - If so, it may serve the community better to release it as two separate plugins - If the two tasks are different, but very closely related, it's probably OK ## How should newlines be represented in plugin output? Always use `\n` to prevent diff issues between operating systems. ## Where can I get updates on gulp? gulp updates can be found on the following twitters: - [@wearefractal](https://twitter.com/wearefractal) - [@eschoff](https://twitter.com/eschoff) - [@gulpjs](https://twitter.com/gulpjs) ## Does gulp have an IRC channel? Yes, come chat with us in #gulpjs on [Freenode]. [Writing a gulp plugin]: writing-a-plugin/README.md [gulp introduction slideshow]: http://slid.es/contra/gulp [Freenode]: http://freenode.net/ [search-gulp-plugins]: http://gulpjs.com/plugins/ [npm plugin search]: https://npmjs.org/browse/keyword/gulpplugin gulp-3.9.1/docs/README.md000066400000000000000000000055771265616124500147300ustar00rootroot00000000000000# gulp documentation * [Getting Started](getting-started.md) - How to get going with gulp * [API documentation](API.md) - Learn the ins and outs of using gulp * [CLI documentation](CLI.md) - Learn how to call tasks and use compilers * [Writing a Plugin](writing-a-plugin/README.md) - So you're writing a gulp plugin? Go here for the essential dos and don'ts. * [Spanish documentation][SpanishDocs] - gulp en Español. * [Simplified Chinese documentation][SimplifiedChineseDocs] - gulp 简体中文文档. * [Korean documentation][KoreanDocs] - gulp 한국어 참조 문서. ## FAQ See the [FAQ](FAQ.md) for the answers to commonly asked questions. ## Recipes The community has written [recipes](recipes#recipes) for common gulp use-cases. ## Still got questions? Post on [StackOverflow with a #gulp tag](http://stackoverflow.com/questions/tagged/gulp), or come chat with us in [#gulpjs](http://webchat.freenode.net/?channels=gulpjs) on [Freenode](http://freenode.net/). ## Books * [Developing a gulp Edge](http://shop.oreilly.com/product/9781939902146.do) ## Articles * [Tagtree intro to gulp video](http://tagtree.tv/gulp) * [Introduction to node.js streams](https://github.com/substack/stream-handbook) * [Video introduction to node.js streams](http://www.youtube.com/watch?v=QgEuZ52OZtU) * [Getting started with gulp (by @markgdyr)](http://markgoodyear.com/2014/01/getting-started-with-gulp/) * [A cheatsheet for gulp](https://github.com/osscafe/gulp-cheatsheet) * [Why you shouldn’t create a gulp plugin (or, how to stop worrying and learn to love existing node packages)](http://blog.overzealous.com/post/74121048393/why-you-shouldnt-create-a-gulp-plugin-or-how-to-stop) * [Inspiration (slides) about why gulp was made](http://slid.es/contra/gulp) * [Building With Gulp](http://www.smashingmagazine.com/2014/06/11/building-with-gulp/) * [Gulp - The Basics (screencast)](https://www.youtube.com/watch?v=dwSLFai8ovQ) * [Get started with gulp (video series)](http://www.youtube.com/playlist?list=PLRk95HPmOM6PN-G1xyKj9q6ap_dc9Yckm) * [Optimize your web code with gulp](http://www.linuxuser.co.uk/tutorials/optimise-your-web-code-with-gulp-js) * [Automate Your Tasks Easily with Gulp.js ](https://scotch.io/tutorials/automate-your-tasks-easily-with-gulp-js) ## Examples - [Web Starter Kit gulpfile](https://github.com/google/web-starter-kit/blob/master/gulpfile.babel.js) ## License All the documentation is covered by the CC0 license *(do whatever you want with it - public domain)*. [![CC0](http://i.creativecommons.org/p/zero/1.0/88x31.png)](http://creativecommons.org/publicdomain/zero/1.0/) To the extent possible under law, [Fractal](http://wearefractal.com) has waived all copyright and related or neighboring rights to this work. [SpanishDocs]: https://github.com/bucaran/gulp-docs-es [SimplifiedChineseDocs]: https://github.com/lisposter/gulp-docs-zh-cn [KoreanDocs]: https://github.com/preco21/gulp-docs-ko gulp-3.9.1/docs/getting-started.md000066400000000000000000000022531265616124500170640ustar00rootroot00000000000000# Getting Started #### 1. Install gulp globally: __If you have previously installed a version of gulp globally, please run `npm rm --global gulp` to make sure your old version doesn't collide with gulp-cli.__ ```sh $ npm install --global gulp-cli ``` #### 2. Install gulp in your project devDependencies: ```sh $ npm install --save-dev gulp ``` #### 3. Create a `gulpfile.js` at the root of your project: ```js var gulp = require('gulp'); gulp.task('default', function() { // place code for your default task here }); ``` #### 4. Run gulp: ```sh $ gulp ``` The default task will run and do nothing. To run individual tasks, use `gulp `. ## Where do I go now? You have an empty gulpfile and everything is installed. How do you REALLY get started? Check out the [recipes](recipes) and the [list of articles](README.md#articles) for more information. ## .src, .watch, .dest, CLI args - How do I use these things? For API specific documentation you can check out the [documentation for that](API.md). ## Available Plugins The gulp community is growing, with new plugins being added daily. See the [main website](http://gulpjs.com/plugins/) for a complete list. gulp-3.9.1/docs/recipes/000077500000000000000000000000001265616124500150655ustar00rootroot00000000000000gulp-3.9.1/docs/recipes/README.md000066400000000000000000000032061265616124500163450ustar00rootroot00000000000000# Recipes * [Automate release workflow](automate-release-workflow.md) * [Combining streams to handle errors](combining-streams-to-handle-errors.md) * [Delete files and folders](delete-files-folder.md) * [Fast browserify builds with watchify](fast-browserify-builds-with-watchify.md) * [Incremental rebuilding, including operating on full file sets](incremental-builds-with-concatenate.md) * [Make stream from buffer (memory contents)](make-stream-from-buffer.md) * [Mocha test-runner with gulp](mocha-test-runner-with-gulp.md) * [Only pass through changed files](only-pass-through-changed-files.md) * [Pass parameters from the command line](pass-arguments-from-cli.md) * [Rebuild only files that change](rebuild-only-files-that-change.md) * [Generating a file per folder](running-task-steps-per-folder.md) * [Running tasks in series](running-tasks-in-series.md) * [Server with live-reloading and CSS injection](server-with-livereload-and-css-injection.md) * [Sharing streams with stream factories](sharing-streams-with-stream-factories.md) * [Specifying a new cwd (current working directory)](specifying-a-cwd.md) * [Split tasks across multiple files](split-tasks-across-multiple-files.md) * [Using external config file](using-external-config-file.md) * [Using multiple sources in one task](using-multiple-sources-in-one-task.md) * [Browserify + Uglify with sourcemaps](browserify-uglify-sourcemap.md) * [Browserify + Globs](browserify-with-globs.md) * [Output both a minified and non-minified version](minified-and-non-minified.md) * [Templating with Swig and YAML front-matter](templating-with-swig-and-yaml-front-matter.md) * [Exports as tasks](exports-as-tasks.md) gulp-3.9.1/docs/recipes/automate-release-workflow.md000066400000000000000000000052721265616124500225220ustar00rootroot00000000000000# Automate release workflow If your project follows a semantic versioning, it may be a good idea to automatize the steps needed to do a release. Below you have a simple recipe that bumps the project version, commits the changes to git and creates a new tag. ``` javascript var gulp = require('gulp'); var runSequence = require('run-sequence'); var conventionalChangelog = require('gulp-conventional-changelog'); var conventionalGithubReleaser = require('conventional-github-releaser'); var bump = require('gulp-bump'); var gutil = require('gulp-util'); var git = require('gulp-git'); var fs = require('fs'); gulp.task('changelog', function () { return gulp.src('CHANGELOG.md', { buffer: false }) .pipe(conventionalChangelog({ preset: 'angular' // Or to any other commit message convention you use. })) .pipe(gulp.dest('./')); }); gulp.task('github-release', function(done) { conventionalGithubReleaser({ type: "oauth", token: '0126af95c0e2d9b0a7c78738c4c00a860b04acc8' // change this to your own GitHub token or use an environment variable }, { preset: 'angular' // Or to any other commit message convention you use. }, done); }); gulp.task('bump-version', function () { // We hardcode the version change type to 'patch' but it may be a good idea to // use minimist (https://www.npmjs.com/package/minimist) to determine with a // command argument whether you are doing a 'major', 'minor' or a 'patch' change. return gulp.src(['./bower.json', './package.json']) .pipe(bump({type: "patch"}).on('error', gutil.log)) .pipe(gulp.dest('./')); }); gulp.task('commit-changes', function () { return gulp.src('.') .pipe(git.add()) .pipe(git.commit('[Prerelease] Bumped version number')); }); gulp.task('push-changes', function (cb) { git.push('origin', 'master', cb); }); gulp.task('create-new-tag', function (cb) { var version = getPackageJsonVersion(); git.tag(version, 'Created Tag for version: ' + version, function (error) { if (error) { return cb(error); } git.push('origin', 'master', {args: '--tags'}, cb); }); function getPackageJsonVersion () { // We parse the json file instead of using require because require caches // multiple calls so the version number won't be updated return JSON.parse(fs.readFileSync('./package.json', 'utf8')).version; }; }); gulp.task('release', function (callback) { runSequence( 'bump-version', 'changelog', 'commit-changes', 'push-changes', 'create-new-tag', 'github-release', function (error) { if (error) { console.log(error.message); } else { console.log('RELEASE FINISHED SUCCESSFULLY'); } callback(error); }); }); ``` gulp-3.9.1/docs/recipes/browserify-transforms.md000066400000000000000000000025221265616124500217770ustar00rootroot00000000000000# Browserify + Transforms [Browserify](http://github.com/substack/node-browserify) has become an important and indispensable tool but requires being wrapped before working well with gulp. Below is a simple recipe for using Browserify with transforms. See also: the [Combining Streams to Handle Errors](https://github.com/gulpjs/gulp/blob/master/docs/recipes/combining-streams-to-handle-errors.md) recipe for handling errors with browserify or uglify in your stream. ``` javascript 'use strict'; var browserify = require('browserify'); var gulp = require('gulp'); var source = require('vinyl-source-stream'); var buffer = require('vinyl-buffer'); var gutil = require('gulp-util'); var uglify = require('gulp-uglify'); var sourcemaps = require('gulp-sourcemaps'); var reactify = require('reactify'); gulp.task('javascript', function () { // set up the browserify instance on a task basis var b = browserify({ entries: './entry.js', debug: true, // defining transforms here will avoid crashing your stream transform: [reactify] }); return b.bundle() .pipe(source('app.js')) .pipe(buffer()) .pipe(sourcemaps.init({loadMaps: true})) // Add transformation tasks to the pipeline here. .pipe(uglify()) .on('error', gutil.log) .pipe(sourcemaps.write('./')) .pipe(gulp.dest('./dist/js/')); }); ``` gulp-3.9.1/docs/recipes/browserify-uglify-sourcemap.md000066400000000000000000000024231265616124500230740ustar00rootroot00000000000000# Browserify + Uglify2 with sourcemaps [Browserify](http://github.com/substack/node-browserify) has become an important and indispensable tool but requires being wrapped before working well with gulp. Below is a simple recipe for using Browserify with full sourcemaps that resolve to the original individual files. See also: the [Combining Streams to Handle Errors](https://github.com/gulpjs/gulp/blob/master/docs/recipes/combining-streams-to-handle-errors.md) recipe for handling errors with browserify or uglify in your stream. ``` javascript 'use strict'; var browserify = require('browserify'); var gulp = require('gulp'); var source = require('vinyl-source-stream'); var buffer = require('vinyl-buffer'); var uglify = require('gulp-uglify'); var sourcemaps = require('gulp-sourcemaps'); var gutil = require('gulp-util'); gulp.task('javascript', function () { // set up the browserify instance on a task basis var b = browserify({ entries: './entry.js', debug: true }); return b.bundle() .pipe(source('app.js')) .pipe(buffer()) .pipe(sourcemaps.init({loadMaps: true})) // Add transformation tasks to the pipeline here. .pipe(uglify()) .on('error', gutil.log) .pipe(sourcemaps.write('./')) .pipe(gulp.dest('./dist/js/')); }); ``` gulp-3.9.1/docs/recipes/browserify-with-globs.md000066400000000000000000000044261265616124500216650ustar00rootroot00000000000000# Browserify + Globs [Browserify + Uglify2](https://github.com/gulpjs/gulp/blob/master/docs/recipes/browserify-uglify-sourcemap.md) shows how to setup a basic gulp task to bundle a JavaScript file with it's dependencies, and minify the bundle with UglifyJS while preserving source maps. It does not, however, show how one may use gulp and Browserify with multiple entry files. See also: the [Combining Streams to Handle Errors](https://github.com/gulpjs/gulp/blob/master/docs/recipes/combining-streams-to-handle-errors.md) recipe for handling errors with Browserify or UglifyJS in your stream. ``` javascript 'use strict'; var browserify = require('browserify'); var gulp = require('gulp'); var source = require('vinyl-source-stream'); var buffer = require('vinyl-buffer'); var globby = require('globby'); var through = require('through2'); var gutil = require('gulp-util'); var uglify = require('gulp-uglify'); var sourcemaps = require('gulp-sourcemaps'); var reactify = require('reactify'); gulp.task('javascript', function () { // gulp expects tasks to return a stream, so we create one here. var bundledStream = through(); bundledStream // turns the output bundle stream into a stream containing // the normal attributes gulp plugins expect. .pipe(source('app.js')) // the rest of the gulp task, as you would normally write it. // here we're copying from the Browserify + Uglify2 recipe. .pipe(buffer()) .pipe(sourcemaps.init({loadMaps: true})) // Add gulp plugins to the pipeline here. .pipe(uglify()) .on('error', gutil.log) .pipe(sourcemaps.write('./')) .pipe(gulp.dest('./dist/js/')); // "globby" replaces the normal "gulp.src" as Browserify // creates it's own readable stream. globby(['./entries/*.js']).then(function(entries) { // create the Browserify instance. var b = browserify({ entries: entries, debug: true, transform: [reactify] }); // pipe the Browserify stream into the stream we created earlier // this starts our gulp pipeline. b.bundle().pipe(bundledStream); }).catch(function(err) { // ensure any errors from globby are handled bundledStream.emit('error', err); }); // finally, we return the stream, so gulp knows when this task is done. return bundledStream; }); ``` gulp-3.9.1/docs/recipes/combining-streams-to-handle-errors.md000066400000000000000000000016741265616124500242230ustar00rootroot00000000000000# Combining streams to handle errors By default, emitting an error on a stream will cause it to be thrown unless it already has a listener attached to the `error` event. This gets a bit tricky when you're working with longer pipelines of streams. By using [stream-combiner2](https://github.com/substack/stream-combiner2) you can turn a series of streams into a single stream, meaning you only need to listen to the `error` event in one place in your code. Here's an example of using it in a gulpfile: ```js var combiner = require('stream-combiner2'); var uglify = require('gulp-uglify'); var gulp = require('gulp'); gulp.task('test', function() { var combined = combiner.obj([ gulp.src('bootstrap/js/*.js'), uglify(), gulp.dest('public/bootstrap') ]); // any errors in the above streams will get caught // by this listener, instead of being thrown: combined.on('error', console.error.bind(console)); return combined; }); ``` gulp-3.9.1/docs/recipes/delete-files-folder.md000066400000000000000000000042641265616124500212300ustar00rootroot00000000000000 # Delete files and folders You might want to delete some files before running your build. Since deleting files doesn't work on the file contents, there's no reason to use a gulp plugin. An excellent opportunity to use a vanilla node module. Let's use the [`del`](https://github.com/sindresorhus/del) module for this example as it supports multiple files and [globbing](https://github.com/sindresorhus/multimatch#globbing-patterns): ```sh $ npm install --save-dev gulp del ``` Imagine the following file structure: ``` . ├── dist │   ├── report.csv │   ├── desktop │   └── mobile │   ├── app.js │   ├── deploy.json │   └── index.html └── src ``` In the gulpfile we want to clean out the contents of the `mobile` folder before running our build: ```js var gulp = require('gulp'); var del = require('del'); gulp.task('clean:mobile', function () { return del([ 'dist/report.csv', // here we use a globbing pattern to match everything inside the `mobile` folder 'dist/mobile/**/*', // we don't want to clean this file though so we negate the pattern '!dist/mobile/deploy.json' ]); }); gulp.task('default', ['clean:mobile']); ``` ## Delete files in a pipeline You might want to delete some files after processing them in a pipeline. We'll use [vinyl-paths](https://github.com/sindresorhus/vinyl-paths) to easily get the file path of files in the stream and pass it to the `del` method. ```sh $ npm install --save-dev gulp del vinyl-paths ``` Imagine the following file structure: ``` . ├── tmp │   ├── rainbow.js │   └── unicorn.js └── dist ``` ```js var gulp = require('gulp'); var stripDebug = require('gulp-strip-debug'); // only as an example var del = require('del'); var vinylPaths = require('vinyl-paths'); gulp.task('clean:tmp', function () { return gulp.src('tmp/*') .pipe(vinylPaths(del)) .pipe(stripDebug()) .pipe(gulp.dest('dist')); }); gulp.task('default', ['clean:tmp']); ``` This will only delete the tmp dir. Only do this if you're already using other plugins in the pipeline, otherwise just use the module directly as `gulp.src` is costly. gulp-3.9.1/docs/recipes/exports-as-tasks.md000066400000000000000000000005531265616124500206420ustar00rootroot00000000000000# Exports as Tasks Using the ES2015 module syntax you can use your exports as tasks. ```js import gulp from 'gulp'; import babel from 'gulp-babel'; // named task export function build() { return gulp.src('src/*.js') .pipe(babel()) .pipe(gulp.dest('lib')); } // default task export default function dev() { gulp.watch('src/*.js', ['build']); } ``` gulp-3.9.1/docs/recipes/fast-browserify-builds-with-watchify.md000066400000000000000000000041661265616124500246110ustar00rootroot00000000000000# Fast browserify builds with watchify As a [browserify](http://github.com/substack/node-browserify) project begins to expand, the time to bundle it slowly gets longer and longer. While it might start at 1 second, it's possible to be waiting 30 seconds for your project to build on particularly large projects. That's why [substack](http://github.com/substack) wrote [watchify](http://github.com/substack/watchify), a persistent browserify bundler that watches files for changes and *only rebuilds what it needs to*. This way, that first build might still take 30 seconds, but subsequent builds can still run in under 100ms – which is a huge improvement. Watchify doesn't have a gulp plugin, and it doesn't need one: you can use [vinyl-source-stream](http://github.com/hughsk/vinyl-source-stream) to pipe the bundle stream into your gulp pipeline. ``` javascript 'use strict'; var watchify = require('watchify'); var browserify = require('browserify'); var gulp = require('gulp'); var source = require('vinyl-source-stream'); var buffer = require('vinyl-buffer'); var gutil = require('gulp-util'); var sourcemaps = require('gulp-sourcemaps'); var assign = require('lodash.assign'); // add custom browserify options here var customOpts = { entries: ['./src/index.js'], debug: true }; var opts = assign({}, watchify.args, customOpts); var b = watchify(browserify(opts)); // add transformations here // i.e. b.transform(coffeeify); gulp.task('js', bundle); // so you can run `gulp js` to build the file b.on('update', bundle); // on any dep update, runs the bundler b.on('log', gutil.log); // output build logs to terminal function bundle() { return b.bundle() // log errors if they happen .on('error', gutil.log.bind(gutil, 'Browserify Error')) .pipe(source('bundle.js')) // optional, remove if you don't need to buffer file contents .pipe(buffer()) // optional, remove if you dont want sourcemaps .pipe(sourcemaps.init({loadMaps: true})) // loads map from browserify file // Add transformation tasks to the pipeline here. .pipe(sourcemaps.write('./')) // writes .map file .pipe(gulp.dest('./dist')); } ``` gulp-3.9.1/docs/recipes/handling-the-delete-event-on-watch.md000066400000000000000000000022421265616124500240460ustar00rootroot00000000000000# Handling the Delete Event on Watch You can listen for `'change'` events to fire on the watcher returned from `gulp.watch`. Each change event has a `type` property. If `type` is `'deleted'`, you can delete the file from your destination directory, using something like: ```js 'use strict'; var del = require('del'); var path = require('path'); var gulp = require('gulp'); var header = require('gulp-header'); var footer = require('gulp-footer'); gulp.task('scripts', function() { return gulp.src('src/**/*.js', {base: 'src'}) .pipe(header('(function () {\r\n\t\'use strict\'\r\n')) .pipe(footer('\r\n})();')) .pipe(gulp.dest('build')); }); gulp.task('watch', function () { var watcher = gulp.watch('src/**/*.js', ['scripts']); watcher.on('change', function (event) { if (event.type === 'deleted') { // Simulating the {base: 'src'} used with gulp.src in the scripts task var filePathFromSrc = path.relative(path.resolve('src'), event.path); // Concatenating the 'build' absolute path used by gulp.dest in the scripts task var destFilePath = path.resolve('build', filePathFromSrc); del.sync(destFilePath); } }); }); ``` gulp-3.9.1/docs/recipes/incremental-builds-with-concatenate.md000066400000000000000000000034311265616124500244240ustar00rootroot00000000000000# Incremental rebuilding, including operating on full file sets The trouble with incremental rebuilds is you often want to operate on _all_ processed files, not just single files. For example, you may want to lint and module-wrap just the file(s) that have changed, then concatenate it with all other linted and module-wrapped files. This is difficult without the use of temp files. Use [gulp-cached](https://github.com/wearefractal/gulp-cached) and [gulp-remember](https://github.com/ahaurw01/gulp-remember) to achieve this. ```js var gulp = require('gulp'); var header = require('gulp-header'); var footer = require('gulp-footer'); var concat = require('gulp-concat'); var jshint = require('gulp-jshint'); var cached = require('gulp-cached'); var remember = require('gulp-remember'); var scriptsGlob = 'src/**/*.js'; gulp.task('scripts', function() { return gulp.src(scriptsGlob) .pipe(cached('scripts')) // only pass through changed files .pipe(jshint()) // do special things to the changed files... .pipe(header('(function () {')) // e.g. jshinting ^^^ .pipe(footer('})();')) // and some kind of module wrapping .pipe(remember('scripts')) // add back all files to the stream .pipe(concat('app.js')) // do things that require all files .pipe(gulp.dest('public/')); }); gulp.task('watch', function () { var watcher = gulp.watch(scriptsGlob, ['scripts']); // watch the same files in our scripts task watcher.on('change', function (event) { if (event.type === 'deleted') { // if a file is deleted, forget about it delete cached.caches.scripts[event.path]; // gulp-cached remove api remember.forget('scripts', event.path); // gulp-remember remove api } }); }); ``` gulp-3.9.1/docs/recipes/maintain-directory-structure-while-globbing.md000066400000000000000000000026031265616124500261370ustar00rootroot00000000000000# Maintain Directory Structure while Globbing If you are planning to read a few files/folders from a directory and maintain their relative path, you need to pass `{base: '.'}` as the second argument to `gulp.src()`. For example, if you have a directory structure like ![Dev setup](https://cloud.githubusercontent.com/assets/2562992/3178498/bedf75b4-ec1a-11e3-8a71-a150ad94b450.png) and want to read only a few files say ```js [ 'index.html', 'css/**', 'js/**', 'lib/**', 'images/**', 'plugin/**' ] ``` In this case, Gulp will read all the sub-folders of (_say_) `css` folder and arrange them relative to your root folder and they will no longer be the sub-folder of `css`. The output after globbing would look like ![Zipped-Unzipped](https://cloud.githubusercontent.com/assets/2562992/3178614/27208c52-ec1c-11e3-852e-8bbb8e420c7f.png) If you want to maintain the structure, you need to pass `{base: '.'}` to `gulp.src()`. Like ```js gulp.task('task', function () { gulp.src(['index.html', 'css/**', 'js/**', 'lib/**', 'images/**', 'plugin/**' ], {base: '.'}) .pipe(operation1()) .pipe(operation2()); }); ``` And the input to your `operation1()` will be a folder structure like ![with-base](https://cloud.githubusercontent.com/assets/2562992/3178607/053d6722-ec1c-11e3-9ba8-7ce39e1a480e.png) gulp-3.9.1/docs/recipes/make-stream-from-buffer.md000066400000000000000000000105011265616124500220220ustar00rootroot00000000000000# Make stream from buffer (memory contents) Sometimes you may need to start a stream with files that their contents are in a variable and not in a physical file. In other words, how to start a 'gulp' stream without using `gulp.src()`. Let's say for example that we have a directory with js lib files and another directory with versions of some module. The target of the build would be to create one js file for each version, containing all the libs and the version of the module concatenated. Logically we would break it down like this: * load the lib files * concatenate the lib file contents * load the versions files * for each version file, concatenate the libs' contents and the version file contents * for each version file, output the result in a file Imagine this file structure: ```sh ├── libs │   ├── lib1.js │   └── lib2.js └── versions ├── version.1.js └── version.2.js ``` You should get: ```sh └── output ├── version.1.complete.js # lib1.js + lib2.js + version.1.js └── version.2.complete.js # lib1.js + lib2.js + version.2.js ``` A simple and modular way to do this would be the following: ```js var gulp = require('gulp'); var runSequence = require('run-sequence'); var source = require('vinyl-source-stream'); var vinylBuffer = require('vinyl-buffer'); var tap = require('gulp-tap'); var concat = require('gulp-concat'); var size = require('gulp-size'); var path = require('path'); var es = require('event-stream'); var memory = {}; // we'll keep our assets in memory // task of loading the files' contents in memory gulp.task('load-lib-files', function() { // read the lib files from the disk return gulp.src('src/libs/*.js') // concatenate all lib files into one .pipe(concat('libs.concat.js')) // tap into the stream to get each file's data .pipe(tap(function(file) { // save the file contents in memory memory[path.basename(file.path)] = file.contents.toString(); })); }); gulp.task('load-versions', function() { memory.versions = {}; // read the version files from the disk return gulp.src('src/versions/version.*.js') // tap into the stream to get each file's data .pipe( tap(function(file) { // save the file contents in the assets memory.versions[path.basename(file.path)] = file.contents.toString(); })); }); gulp.task('write-versions', function() { // we store all the different version file names in an array var availableVersions = Object.keys(memory.versions); // we make an array to store all the stream promises var streams = []; availableVersions.forEach(function(v) { // make a new stream with fake file name var stream = source('final.' + v); var streamEnd = stream; // we load the data from the concatenated libs var fileContents = memory['libs.concat.js'] + // we add the version's data '\n' + memory.versions[v]; // write the file contents to the stream stream.write(fileContents); process.nextTick(function() { // in the next process cycle, end the stream stream.end(); }); streamEnd = streamEnd // transform the raw data into the stream, into a vinyl object/file .pipe(vinylBuffer()) //.pipe(tap(function(file) { /* do something with the file contents here */ })) .pipe(gulp.dest('output')); // add the end of the stream, otherwise the task would finish before all the processing // is done streams.push(streamEnd); }); return es.merge.apply(this, streams); }); //============================================ our main task gulp.task('default', function(taskDone) { runSequence( ['load-lib-files', 'load-versions'], // load the files in parallel 'write-versions', // ready to write once all resources are in memory taskDone // done ); }); //============================================ our watcher task // only watch after having run 'default' once so that all resources // are already in memory gulp.task('watch', ['default'], function() { gulp.watch('./src/libs/*.js', function() { runSequence( 'load-lib-files', // we only have to load the changed files 'write-versions' ); }); gulp.watch('./src/versions/*.js', function() { runSequence( 'load-versions', // we only have to load the changed files 'write-versions' ); }); }); ``` gulp-3.9.1/docs/recipes/minified-and-non-minified.md000066400000000000000000000012561265616124500223110ustar00rootroot00000000000000# Output both a minified and non-minified version Outputting both a minified and non-minified version of your combined JavaScript files can be achieved by using `gulp-rename` and piping to `dest` twice (once before minifying and once after minifying): ```js 'use strict'; var gulp = require('gulp'); var rename = require('gulp-rename'); var uglify = require('gulp-uglify'); var DEST = 'build/'; gulp.task('default', function() { return gulp.src('foo.js') // This will output the non-minified version .pipe(gulp.dest(DEST)) // This will minify and rename to foo.min.js .pipe(uglify()) .pipe(rename({ extname: '.min.js' })) .pipe(gulp.dest(DEST)); }); ``` gulp-3.9.1/docs/recipes/mocha-test-runner-with-gulp.md000066400000000000000000000014771265616124500227110ustar00rootroot00000000000000# Mocha test-runner with gulp ### Passing shared module in all tests ```js // npm install gulp gulp-mocha var gulp = require('gulp'); var mocha = require('gulp-mocha'); gulp.task('default', function() { return gulp.src(['test/test-*.js'], { read: false }) .pipe(mocha({ reporter: 'spec', globals: { should: require('should') } })); }); ``` ### Running mocha tests when files change ```js // npm install gulp gulp-mocha gulp-util var gulp = require('gulp'); var mocha = require('gulp-mocha'); var gutil = require('gulp-util'); gulp.task('mocha', function() { return gulp.src(['test/*.js'], { read: false }) .pipe(mocha({ reporter: 'list' })) .on('error', gutil.log); }); gulp.task('watch-mocha', function() { gulp.watch(['lib/**', 'test/**'], ['mocha']); }); ``` gulp-3.9.1/docs/recipes/only-pass-through-changed-files.md000066400000000000000000000016071265616124500235050ustar00rootroot00000000000000# Only pass through changed files Files are passed through the whole pipe chain on every run by default. By using [gulp-changed](https://github.com/sindresorhus/gulp-changed) only changed files will be passed through. This can speed up consecutive runs considerably. ```js // npm install --save-dev gulp gulp-changed gulp-jscs gulp-uglify var gulp = require('gulp'); var changed = require('gulp-changed'); var jscs = require('gulp-jscs'); var uglify = require('gulp-uglify'); // we define some constants here so they can be reused var SRC = 'src/*.js'; var DEST = 'dist'; gulp.task('default', function() { return gulp.src(SRC) // the `changed` task needs to know the destination directory // upfront to be able to figure out which files changed .pipe(changed(DEST)) // only files that has changed will pass through here .pipe(jscs()) .pipe(uglify()) .pipe(gulp.dest(DEST)); }); ``` gulp-3.9.1/docs/recipes/pass-arguments-from-cli.md000066400000000000000000000012211265616124500220620ustar00rootroot00000000000000# Pass arguments from the command line ```js // npm install --save-dev gulp gulp-if gulp-uglify minimist var gulp = require('gulp'); var gulpif = require('gulp-if'); var uglify = require('gulp-uglify'); var minimist = require('minimist'); var knownOptions = { string: 'env', default: { env: process.env.NODE_ENV || 'production' } }; var options = minimist(process.argv.slice(2), knownOptions); gulp.task('scripts', function() { return gulp.src('**/*.js') .pipe(gulpif(options.env === 'production', uglify())) // only minify in production .pipe(gulp.dest('dist')); }); ``` Then run gulp with: ```sh $ gulp scripts --env development ``` gulp-3.9.1/docs/recipes/rebuild-only-files-that-change.md000066400000000000000000000005431265616124500232770ustar00rootroot00000000000000# Rebuild only files that change With [`gulp-watch`](https://github.com/floatdrop/gulp-watch): ```js var gulp = require('gulp'); var sass = require('gulp-sass'); var watch = require('gulp-watch'); gulp.task('default', function() { return gulp.src('sass/*.scss') .pipe(watch('sass/*.scss')) .pipe(sass()) .pipe(gulp.dest('dist')); }); ``` gulp-3.9.1/docs/recipes/running-task-steps-per-folder.md000066400000000000000000000034501265616124500232220ustar00rootroot00000000000000# Generating a file per folder If you have a set of folders, and wish to perform a set of tasks on each, for instance... ``` /scripts /scripts/jquery/*.js /scripts/angularjs/*.js ``` ...and want to end up with... ``` /scripts /scripts/jquery.min.js /scripts/angularjs.min.js ``` ...you'll need to do something like the following... ``` javascript var fs = require('fs'); var path = require('path'); var merge = require('merge-stream'); var gulp = require('gulp'); var concat = require('gulp-concat'); var rename = require('gulp-rename'); var uglify = require('gulp-uglify'); var scriptsPath = 'src/scripts'; function getFolders(dir) { return fs.readdirSync(dir) .filter(function(file) { return fs.statSync(path.join(dir, file)).isDirectory(); }); } gulp.task('scripts', function() { var folders = getFolders(scriptsPath); var tasks = folders.map(function(folder) { // concat into foldername.js // write to output // minify // rename to folder.min.js // write to output again return gulp.src(path.join(scriptsPath, folder, '/**/*.js')) .pipe(concat(folder + '.js')) .pipe(gulp.dest(scriptsPath)) .pipe(uglify()) .pipe(rename(folder + '.min.js')) .pipe(gulp.dest(scriptsPath)); }); // process all remaining files in scriptsPath root into main.js and main.min.js files var root = gulp.src(path.join(scriptsPath, '/*.js')) .pipe(concat('main.js')) .pipe(gulp.dest(scriptsPath)) .pipe(uglify()) .pipe(rename('main.min.js')) .pipe(gulp.dest(scriptsPath)); return merge(tasks, root); }); ``` A few notes: - `folders.map` - executes the function once per folder, and returns the async stream - `merge` - combines the streams and ends only when all streams emitted end gulp-3.9.1/docs/recipes/running-tasks-in-series.md000066400000000000000000000045421265616124500221130ustar00rootroot00000000000000# Running tasks in series, i.e. Task Dependency By default, tasks run with maximum concurrency -- e.g. it launches all the tasks at once and waits for nothing. If you want to create a series where tasks run in a particular order, you need to do two things: - give it a hint to tell it when the task is done, - and give it a hint that a task depends on completion of another. For these examples, let's presume you have two tasks, "one" and "two" that you specifically want to run in this order: 1. In task "one" you add a hint to tell it when the task is done. Either take in a callback and call it when you're done or return a promise or stream that the engine should wait to resolve or end respectively. 2. In task "two" you add a hint telling the engine that it depends on completion of the first task. So this example would look like: ```js var gulp = require('gulp'); // takes in a callback so the engine knows when it'll be done gulp.task('one', function (cb) { // do stuff -- async or otherwise fs.writeFile('filename', 'data', opts, function (err) { cb(err); // if err is not null and not undefined, the orchestration will stop, and 'two' will not run }); }); // identifies a dependent task must be complete before this one begins gulp.task('two', ['one'], function() { // task 'one' is done now }); gulp.task('default', ['one', 'two']); // alternatively: gulp.task('default', ['two']); ``` Another example, which returns the stream instead of using a callback: ```js var gulp = require('gulp'); var del = require('del'); // rm -rf gulp.task('clean', function() { return del(['output']); }); gulp.task('templates', ['clean'], function() { var stream = gulp.src(['src/templates/*.hbs']) // do some concatenation, minification, etc. .pipe(gulp.dest('output/templates/')); return stream; // return the stream as the completion hint }); gulp.task('styles', ['clean'], function() { var stream = gulp.src(['src/styles/app.less']) // do some hinting, minification, etc. .pipe(gulp.dest('output/css/app.css')); return stream; }); gulp.task('build', ['templates', 'styles']); // templates and styles will be processed in parallel. // clean will be guaranteed to complete before either start. // clean will not be run twice, even though it is called as a dependency twice. gulp.task('default', ['build']); ``` gulp-3.9.1/docs/recipes/server-with-livereload-and-css-injection.md000066400000000000000000000054051265616124500253240ustar00rootroot00000000000000# Server with live-reloading and CSS injection With [BrowserSync](http://browsersync.io) and gulp, you can easily create a development server that is accessible to any device on the same WiFi network. BrowserSync also has live-reload built in, so there's nothing else to configure. First install the module: ```sh $ npm install --save-dev browser-sync ``` Then, considering the following file structure... ``` gulpfile.js app/ styles/ main.css scripts/ main.js index.html ``` ... you can easily serve files from the `app` directory and have all browsers reload when any of them change with the following in `gulpfile.js`: ```js var gulp = require('gulp'); var browserSync = require('browser-sync'); var reload = browserSync.reload; // watch files for changes and reload gulp.task('serve', function() { browserSync({ server: { baseDir: 'app' } }); gulp.watch(['*.html', 'styles/**/*.css', 'scripts/**/*.js'], {cwd: 'app'}, reload); }); ``` and including the CSS in `index.html`: ```html ... ... ``` to serve your files and launch a browser window pointing to the default URL (http://localhost:3000) run: ```bash gulp serve ``` ## + CSS pre-processors A common use-case is to reload CSS files after they've been pre-processed. Using Sass as an example, this is how you can instruct browsers to reload the CSS without doing a full-page refresh. Considering this updated file structure... ``` gulpfile.js app/ scss/ main.scss scripts/ main.js index.html ``` ... you can easily watch Sass files from the `scss` directory and have all browsers reload when any of them change with the following in `gulpfile.js`: ```js var gulp = require('gulp'); var sass = require('gulp-ruby-sass'); var browserSync = require('browser-sync'); var reload = browserSync.reload; gulp.task('sass', function() { return sass('scss/styles.scss') .pipe(gulp.dest('app/css')) .pipe(reload({ stream:true })); }); // watch Sass files for changes, run the Sass preprocessor with the 'sass' task and reload gulp.task('serve', ['sass'], function() { browserSync({ server: { baseDir: 'app' } }); gulp.watch('app/scss/*.scss', ['sass']); }); ``` and including the pre-processed CSS in `index.html`: ```html ... ... ``` to serve your files and launch a browser window pointing to the default URL (http://localhost:3000) run: ```bash gulp serve ``` ## Extras - Live reload, CSS injection and scroll/form syncing works seamlessly inside of [BrowserStack](http://www.browserstack.com/) virtual machines. - Set `tunnel: true` to view your local site at a public URL (complete with all BrowserSync features). gulp-3.9.1/docs/recipes/sharing-streams-with-stream-factories.md000066400000000000000000000037571265616124500247510ustar00rootroot00000000000000# Sharing streams with stream factories If you use the same plugins in multiple tasks you might find yourself getting that itch to DRY things up. This method will allow you to create factories to split out your commonly used stream chains. We'll use [lazypipe](https://github.com/OverZealous/lazypipe) to get the job done. This is our sample file: ```js var gulp = require('gulp'); var uglify = require('gulp-uglify'); var coffee = require('gulp-coffee'); var jshint = require('gulp-jshint'); var stylish = require('jshint-stylish'); gulp.task('bootstrap', function() { return gulp.src('bootstrap/js/*.js') .pipe(jshint()) .pipe(jshint.reporter(stylish)) .pipe(uglify()) .pipe(gulp.dest('public/bootstrap')); }); gulp.task('coffee', function() { return gulp.src('lib/js/*.coffee') .pipe(coffee()) .pipe(jshint()) .pipe(jshint.reporter(stylish)) .pipe(uglify()) .pipe(gulp.dest('public/js')); }); ``` and our file after using lazypipe looks like this: ```js var gulp = require('gulp'); var uglify = require('gulp-uglify'); var coffee = require('gulp-coffee'); var jshint = require('gulp-jshint'); var stylish = require('jshint-stylish'); var lazypipe = require('lazypipe'); // give lazypipe var jsTransform = lazypipe() .pipe(jshint) .pipe(jshint.reporter, stylish) .pipe(uglify); gulp.task('bootstrap', function() { return gulp.src('bootstrap/js/*.js') .pipe(jsTransform()) .pipe(gulp.dest('public/bootstrap')); }); gulp.task('coffee', function() { return gulp.src('lib/js/*.coffee') .pipe(coffee()) .pipe(jsTransform()) .pipe(gulp.dest('public/js')); }); ``` You can see we split out our JavaScript pipeline (JSHint + Uglify) that was being reused in multiple tasks into a factory. These factories can be reused in as many tasks as you want. You can also nest factories and you can chain factories together for great effect. Splitting out each shared pipeline also gives you one central location to modify if you decide to change up your workflow. gulp-3.9.1/docs/recipes/specifying-a-cwd.md000066400000000000000000000007361265616124500205460ustar00rootroot00000000000000# Specifying a new cwd (current working directory) This is helpful for projects using a nested directory structure, such as: ``` /project /layer1 /layer2 ``` You can use the gulp CLI option `--cwd`. From the `project/` directory: ```sh gulp --cwd layer1 ``` If you only need to specify a cwd for a certain glob, you can use the `cwd` option on a [glob-stream](https://github.com/wearefractal/glob-stream): ```js gulp.src('./some/dir/**/*.js', { cwd: 'public' }); ``` gulp-3.9.1/docs/recipes/split-tasks-across-multiple-files.md000066400000000000000000000010471265616124500241100ustar00rootroot00000000000000# Split tasks across multiple files If your `gulpfile.js` is starting to grow too large, you can split the tasks into separate files by using the [require-dir](https://github.com/aseemk/requireDir) module. Imagine the following file structure: ``` gulpfile.js tasks/ ├── dev.js ├── release.js └── test.js ``` Install the `require-dir` module: ```sh npm install --save-dev require-dir ``` Add the following lines to your `gulpfile.js` file: ```js var requireDir = require('require-dir'); var tasks = requireDir('./tasks'); ``` gulp-3.9.1/docs/recipes/templating-with-swig-and-yaml-front-matter.md000066400000000000000000000014531265616124500256160ustar00rootroot00000000000000# Templating with Swig and YAML front-matter Templating can be setup using `gulp-swig` and `gulp-front-matter`: ##### `page.html` ```html --- title: Things to do todos: - First todo - Another todo item - A third todo item --- {{ title }}

{{ title }}

    {% for todo in todos %}
  • {{ todo }}
  • {% endfor %}
``` ##### `gulpfile.js` ```js var gulp = require('gulp'); var swig = require('gulp-swig'); var frontMatter = require('gulp-front-matter'); gulp.task('compile-page', function() { gulp.src('page.html') .pipe(frontMatter({ property: 'data' })) .pipe(swig()) .pipe(gulp.dest('build')); }); gulp.task('default', ['compile-page']); ``` gulp-3.9.1/docs/recipes/using-external-config-file.md000066400000000000000000000015001265616124500225300ustar00rootroot00000000000000# Using external config file Beneficial because it's keeping tasks DRY and config.json can be used by another task runner, like `grunt`. - ###### `config.json` ```json { "desktop" : { "src" : [ "dev/desktop/js/**/*.js", "!dev/desktop/js/vendor/**" ], "dest" : "build/desktop/js" }, "mobile" : { "src" : [ "dev/mobile/js/**/*.js", "!dev/mobile/js/vendor/**" ], "dest" : "build/mobile/js" } } ``` - ###### `gulpfile.js` ```js // npm install --save-dev gulp gulp-uglify var gulp = require('gulp'); var uglify = require('gulp-uglify'); var config = require('./config.json'); function doStuff(cfg) { return gulp.src(cfg.src) .pipe(uglify()) .pipe(gulp.dest(cfg.dest)); } gulp.task('dry', function() { doStuff(config.desktop); doStuff(config.mobile); }); ``` gulp-3.9.1/docs/recipes/using-multiple-sources-in-one-task.md000066400000000000000000000013211265616124500241660ustar00rootroot00000000000000# Using multiple sources in one task ```js // npm install --save-dev gulp merge-stream var gulp = require('gulp'); var merge = require('merge-stream'); gulp.task('test', function() { var bootstrap = gulp.src('bootstrap/js/*.js') .pipe(gulp.dest('public/bootstrap')); var jquery = gulp.src('jquery.cookie/jquery.cookie.js') .pipe(gulp.dest('public/jquery')); return merge(bootstrap, jquery); }); ``` `gulp.src` will emit files in the order they were added: ```js // npm install gulp gulp-concat var gulp = require('gulp'); var concat = require('gulp-concat'); gulp.task('default', function() { return gulp.src(['foo/*', 'bar/*']) .pipe(concat('result.txt')) .pipe(gulp.dest('build')); }); gulp-3.9.1/docs/writing-a-plugin/000077500000000000000000000000001265616124500166305ustar00rootroot00000000000000gulp-3.9.1/docs/writing-a-plugin/README.md000066400000000000000000000171641265616124500201200ustar00rootroot00000000000000# Writing a plugin If you plan to create your own Gulp plugin, you will save time by reading the full documentation. * [Guidelines](guidelines.md) (a MUST read) * [Using buffers](using-buffers.md) * [Dealing with streams](dealing-with-streams.md) * [Testing](testing.md) ## What it does ### Streaming file objects A gulp plugin always returns a stream in [object mode](http://nodejs.org/api/stream.html#stream_object_mode) that does the following: 1. Takes in [vinyl File objects](http://github.com/wearefractal/vinyl) 2. Outputs [vinyl File objects](http://github.com/wearefractal/vinyl) (via `transform.push()` and/or the plugin's callback function) These are known as [transform streams](http://nodejs.org/api/stream.html#stream_class_stream_transform_1) (also sometimes called through streams). Transform streams are streams that are readable and writable; they manipulate objects as they're being passed through. All gulp plugins essentially boil down to this: ```js var Transform = require('transform'); module.exports = function() { // Monkey patch Transform or create your own subclass, // implementing `_transform()` and optionally `_flush()` var transformStream = new Transform({objectMode: true}); /** * @param {Buffer|string} file * @param {string=} encoding - ignored if file contains a Buffer * @param {function(Error, object)} callback - Call this function (optionally with an * error argument and data) when you are done processing the supplied chunk. */ transformStream._transform = function(file, encoding, callback) { var error = null, output = doSomethingWithTheFile(file); callback(error, output); }); return transformStream; }; ``` Many plugins use the [through2](https://github.com/rvagg/through2/) module to simplify their code: ```js var through = require('through2'); // npm install --save through2 module.exports = function() { return through.obj(function(file, encoding, callback) { callback(null, doSomethingWithTheFile(file)); }); }; ``` The stream returned from `through()` (and `this` within your transform function) is an instance of the [Transform](https://github.com/iojs/readable-stream/blob/master/lib/_stream_transform.js) class, which extends [Duplex](https://github.com/iojs/readable-stream/blob/master/lib/_stream_duplex.js), [Readable](https://github.com/iojs/readable-stream/blob/master/lib/_stream_readable.js) (and parasitically from Writable) and ultimately [Stream](https://nodejs.org/api/stream.html). If you need to parse additional options, you can call the `through()` function directly: ```js return through({objectMode: true /* other options... */}, function(file, encoding, callback) { ... ``` Supported options include: * highWaterMark (defaults to 16) * defaultEncoding (defaults to 'utf8') * encoding - 'utf8', 'base64', 'utf16le', 'ucs2' etc. If specified, a [StringDecoder](https://github.com/rvagg/string_decoder/blob/master/index.js) `decoder` will be attached to the stream. * readable {boolean} * writable {boolean} * allowHalfOpen {boolean} If set to false, then the stream will automatically end the readable side when the writable side ends and vice versa. ### Modifying file content The function parameter that you pass to `through.obj()` is a [_transform](https://nodejs.org/api/stream.html#stream_transform_transform_chunk_encoding_callback) function which will operate on the input `file`. You may also provide an optional [_flush](https://nodejs.org/api/stream.html#stream_transform_flush_callback) function if you need to emit a bit more data at the end of the stream. From within your transform function call `this.push(file)` 0 or more times to pass along transformed/cloned files. You don't need to call `this.push(file)` if you provide all output to the `callback()` function. Call the `callback` function only when the current file (stream/buffer) is completely consumed. If an error is encountered, pass it as the first argument to the callback, otherwise set it to null. If you have passed all output data to `this.push()` you can omit the second argument to the callback. Generally, a gulp plugin would update `file.contents` and then choose to either: - call `callback(null, file)` _or_ - make one call to `this.push(file)` If a plugin creates multiple files from a single input file, it would make multiple calls to `this.push()` - eg: ```js module.exports = function() { /** * @this {Transform} */ var transform = function(file, encoding, callback) { var files = splitFile(file); this.push(files[0]); this.push(files[1]); callback(); }; return through.obj(transform); }; ``` The [gulp-unzip](https://github.com/suisho/gulp-unzip/blob/master/index.js) plugin provides a good example of making multiple calls to `push()`. It also uses a chunk transform stream with a `_flush()` function _within_ the Vinyl transform function. Vinyl files can have 3 possible forms for the contents attribute: - [Streams](dealing-with-streams.md) - [Buffers](using-buffers.md) - Empty (null) - Useful for things like rimraf, clean, where contents is not needed. A simple example showing how to detect & handle each form is provided below, for a more detailed explanation of each approach follow the links above. ```js var PluginError = require('gulp-util').PluginError; // consts var PLUGIN_NAME = 'gulp-example'; module.exports = function() { return through.obj(function(file, encoding, callback) { if (file.isNull()) { // nothing to do return callback(null, file); } if (file.isStream()) { // file.contents is a Stream - https://nodejs.org/api/stream.html this.emit('error', new PluginError(PLUGIN_NAME, 'Streams not supported!')); // or, if you can handle Streams: //file.contents = file.contents.pipe(... //return callback(null, file); } else if (file.isBuffer()) { // file.contents is a Buffer - https://nodejs.org/api/buffer.html this.emit('error', new PluginError(PLUGIN_NAME, 'Buffers not supported!')); // or, if you can handle Buffers: //file.contents = ... //return callback(null, file); } }); }; ``` Note: When looking through the code of other gulp plugins (and the example above), you may notice that the transform functions will return the result of the callback: ```js return callback(null, file); ``` ...don't be confused - gulp ignores any return value of your transform function. The code above is simply a short-hand form of: ```js if (someCondition) { callback(null, file); return; } // further execution... ``` ## Useful resources * [File object](https://github.com/wearefractal/gulp-util/#new-fileobj) * [PluginError](https://github.com/gulpjs/gulp-util#new-pluginerrorpluginname-message-options) * [event-stream](https://github.com/dominictarr/event-stream) * [BufferStream](https://github.com/nfroidure/BufferStream) * [gulp-util](https://github.com/wearefractal/gulp-util) ## Sample plugins * [sindresorhus' gulp plugins](https://github.com/search?q=%40sindresorhus+gulp-) * [Fractal's gulp plugins](https://github.com/search?q=%40wearefractal+gulp-) * [gulp-replace](https://github.com/lazd/gulp-replace) ## About streams If you're unfamiliar with streams, you will need to read up on them: * https://github.com/substack/stream-handbook (a MUST read) * http://nodejs.org/api/stream.html Other libraries that are not file manipulating through streams but are made for use with gulp are tagged with the [gulpfriendly](https://npmjs.org/browse/keyword/gulpfriendly) keyword on npm. gulp-3.9.1/docs/writing-a-plugin/dealing-with-streams.md000066400000000000000000000044001265616124500232000ustar00rootroot00000000000000# Dealing with streams > It is highly recommended to write plugins supporting streams. Here is some information on creating a gulp plugin that supports streams. > Make sure to follow the best practice regarding error handling and add the line that make the gulp plugin re-emit the first error caught during the transformation of the content [Writing a Plugin](README.md) > Writing stream based plugins ## Dealing with streams Let's implement a plugin prepending some text to files. This plugin supports all possible forms of file.contents. ```js var through = require('through2'); var gutil = require('gulp-util'); var PluginError = gutil.PluginError; // consts const PLUGIN_NAME = 'gulp-prefixer'; function prefixStream(prefixText) { var stream = through(); stream.write(prefixText); return stream; } // plugin level function (dealing with files) function gulpPrefixer(prefixText) { if (!prefixText) { throw new PluginError(PLUGIN_NAME, 'Missing prefix text!'); } prefixText = new Buffer(prefixText); // allocate ahead of time // creating a stream through which each file will pass var stream = through.obj(function(file, enc, cb) { if (file.isBuffer()) { this.emit('error', new PluginError(PLUGIN_NAME, 'Buffers not supported!')); return cb(); } if (file.isStream()) { // define the streamer that will transform the content var streamer = prefixStream(prefixText); // catch errors from the streamer and emit a gulp plugin error streamer.on('error', this.emit.bind(this, 'error')); // start the transformation file.contents = file.contents.pipe(streamer); } // make sure the file goes through the next gulp plugin this.push(file); // tell the stream engine that we are done with this file cb(); }); // returning the file stream return stream; } // exporting the plugin main function module.exports = gulpPrefixer; ``` The above plugin can be used like this: ```js var gulp = require('gulp'); var gulpPrefixer = require('gulp-prefixer'); gulp.src('files/**/*.js', { buffer: false }) .pipe(gulpPrefixer('prepended string')) .pipe(gulp.dest('modified-files')); ``` ## Some plugins using streams * [gulp-svgicons2svgfont](https://github.com/nfroidure/gulp-svgiconstosvgfont) gulp-3.9.1/docs/writing-a-plugin/guidelines.md000066400000000000000000000132611265616124500213050ustar00rootroot00000000000000# Guidelines > While these guidelines are totally optional, we **HIGHLY** recommend that everyone follows them. Nobody wants to use a bad plugin. These guidelines will actually help make your life easier by giving you assurance that your plugin fits well within gulp. [Writing a Plugin](README.md) > Guidelines 1. Your plugin should not do something that can be done easily with an existing node module - For example: deleting a folder does not need to be a gulp plugin. Use a module like [del](https://github.com/sindresorhus/del) within a task instead. - Wrapping every possible thing just for the sake of wrapping it will pollute the ecosystem with low quality plugins that don't make sense within the gulp paradigm. - gulp plugins are for file-based operations! If you find yourself shoehorning a complex process into streams just make a normal node module instead. - A good example of a gulp plugin would be something like gulp-coffee. The coffee-script module does not work with Vinyl out of the box, so we wrap it to add this functionality and abstract away pain points to make it work well within gulp. 1. Your plugin should only do **one thing**, and do it well. - Avoid config options that make your plugin do completely different tasks - For example: A JS minification plugin should not have an option that adds a header as well 1. Your plugin shouldn't do things that other plugins are responsible for - It should not concat, [gulp-concat](https://github.com/wearefractal/gulp-concat) does that - It should not add headers, [gulp-header](https://github.com/godaddy/gulp-header) does that - It should not add footers, [gulp-footer](https://github.com/godaddy/gulp-footer) does that - If it's a common but optional use case, document that your plugin is often used with another plugin - Make use of other plugins within your plugin! This reduces the amount of code you have to write and ensures a stable ecosystem. 1. Your plugin **must be tested** - Testing a gulp plugin is easy, you don't even need gulp to test it - Look at other plugins for examples 1. Add `gulpplugin` as a keyword in your `package.json` so you show up on our search 1. Do not throw errors inside a stream - Instead, you should emit it as an **error** event. - If you encounter an error **outside** the stream, such as invalid configuration while creating the stream, you may throw it. 1. Prefix any errors with the name of your plugin - For example: `gulp-replace: Cannot do regexp replace on a stream` - Use gulp-util's [PluginError](https://github.com/gulpjs/gulp-util#new-pluginerrorpluginname-message-options) class to make this easy 1. Name your plugin appropriately: it should begin with "gulp-" if it is a gulp plugin - If it is not a gulp plugin, it should not begin with "gulp-" 1. The type of `file.contents` should always be the same going out as it was when it came in - If file.contents is null (non-read) just ignore the file and pass it along - If file.contents is a Stream and you don't support that just emit an error - Do not buffer a stream to shoehorn your plugin to work with streams. This will cause horrible things to happen. 1. Do not pass the `file` object downstream until you are done with it 1. Use [`file.clone()`](https://github.com/wearefractal/vinyl#clone) when cloning a file or creating a new one based on a file. 1. Use modules from our [recommended modules page](recommended-modules.md) to make your life easier 1. Do NOT require `gulp` as a dependency or peerDependency in your plugin - Using gulp to test or automate your plugin workflow is totally cool, just make sure you put it as a devDependency - Requiring gulp as a dependency of your plugin means that anyone who installs your plugin is also installing a new gulp and its entire dependency tree. - There is no reason you should be using gulp within your actual plugin code. If you find yourself doing this open an issue so we can help you out. ## Why are these guidelines so strict? gulp aims to be simple for users. By providing strict guidelines we are able to provide a consistent and high-quality ecosystem for everyone. While this does add a little more work and thought for plugin authors, it removes a lot of problems later down the road. ### What happens if I don't follow them? npm is open for everyone, and you are free to make whatever you want but these guidelines were prescribed for a reason. There are acceptance tests coming soon that will be integrated into the plugin search. If you fail to adhere to the plugin guidelines it will be publicly visible/sortable via a scoring system. People will always prefer to use plugins that match "the gulp way". ### What does a good plugin look like? ```js // through2 is a thin wrapper around node transform streams var through = require('through2'); var gutil = require('gulp-util'); var PluginError = gutil.PluginError; // Consts const PLUGIN_NAME = 'gulp-prefixer'; function prefixStream(prefixText) { var stream = through(); stream.write(prefixText); return stream; } // Plugin level function(dealing with files) function gulpPrefixer(prefixText) { if (!prefixText) { throw new PluginError(PLUGIN_NAME, 'Missing prefix text!'); } prefixText = new Buffer(prefixText); // allocate ahead of time // Creating a stream through which each file will pass return through.obj(function(file, enc, cb) { if (file.isNull()) { // return empty file return cb(null, file); } if (file.isBuffer()) { file.contents = Buffer.concat([prefixText, file.contents]); } if (file.isStream()) { file.contents = file.contents.pipe(prefixStream(prefixText)); } cb(null, file); }); } // Exporting the plugin main function module.exports = gulpPrefixer; ``` gulp-3.9.1/docs/writing-a-plugin/recommended-modules.md000066400000000000000000000011261265616124500231020ustar00rootroot00000000000000# Recommended Modules > Sticking to this curated list of recommended modules will make sure you don't violate the plugin guidelines and ensure consistency across plugins. [Writing a Plugin](README.md) > Recommended Modules #### Replacing a file extension Use [replace-ext](https://github.com/wearefractal/replace-ext) #### Errors Use [BetterError](https://github.com/wearefractal/BetterError) when it is finished #### String colors Use [chalk](https://github.com/sindresorhus/chalk) #### Date formatting Use [dateformat](https://github.com/felixge/node-dateformat) Display as `HH:MM:ss` gulp-3.9.1/docs/writing-a-plugin/testing.md000066400000000000000000000051251265616124500206320ustar00rootroot00000000000000# Testing > Testing your plugin is the only way to ensure quality. It brings confidence to your users and makes your life easier. [Writing a Plugin](README.md) > Testing ## Tooling Most plugins use [mocha](https://github.com/mochajs/mocha), [should](https://github.com/shouldjs/should.js) and [event-stream](https://github.com/dominictarr/event-stream) to help them test. The following examples will use these tools. ## Testing plugins for streaming mode ```js var assert = require('assert'); var es = require('event-stream'); var File = require('vinyl'); var prefixer = require('../'); describe('gulp-prefixer', function() { describe('in streaming mode', function() { it('should prepend text', function(done) { // create the fake file var fakeFile = new File({ contents: es.readArray(['stream', 'with', 'those', 'contents']) }); // Create a prefixer plugin stream var myPrefixer = prefixer('prependthis'); // write the fake file to it myPrefixer.write(fakeFile); // wait for the file to come back out myPrefixer.once('data', function(file) { // make sure it came out the same way it went in assert(file.isStream()); // buffer the contents to make sure it got prepended to file.contents.pipe(es.wait(function(err, data) { // check the contents assert.equal(data, 'prependthisstreamwiththosecontents'); done(); })); }); }); }); }); ``` ## Testing plugins for buffer mode ```js var assert = require('assert'); var es = require('event-stream'); var File = require('vinyl'); var prefixer = require('../'); describe('gulp-prefixer', function() { describe('in buffer mode', function() { it('should prepend text', function(done) { // create the fake file var fakeFile = new File({ contents: new Buffer('abufferwiththiscontent') }); // Create a prefixer plugin stream var myPrefixer = prefixer('prependthis'); // write the fake file to it myPrefixer.write(fakeFile); // wait for the file to come back out myPrefixer.once('data', function(file) { // make sure it came out the same way it went in assert(file.isBuffer()); // check the contents assert.equal(file.contents.toString('utf8'), 'prependthisabufferwiththiscontent'); done(); }); }); }); }); ``` ## Some plugins with high-quality Testing * [gulp-cat](https://github.com/ben-eb/gulp-cat/blob/master/test.js) * [gulp-concat](https://github.com/wearefractal/gulp-concat/blob/master/test/main.js) gulp-3.9.1/docs/writing-a-plugin/using-buffers.md000066400000000000000000000041041265616124500217300ustar00rootroot00000000000000# Using buffers > Here is some information on creating gulp plugin that manipulates buffers. [Writing a Plugin](README.md) > Using buffers ## Using buffers If your plugin is relying on a buffer based library, you will probably choose to base your plugin around file.contents as a buffer. Let's implement a plugin prepending some text to files: ```js var through = require('through2'); var gutil = require('gulp-util'); var PluginError = gutil.PluginError; // consts const PLUGIN_NAME = 'gulp-prefixer'; // plugin level function (dealing with files) function gulpPrefixer(prefixText) { if (!prefixText) { throw new PluginError(PLUGIN_NAME, 'Missing prefix text!'); } prefixText = new Buffer(prefixText); // allocate ahead of time // creating a stream through which each file will pass var stream = through.obj(function(file, enc, cb) { if (file.isStream()) { this.emit('error', new PluginError(PLUGIN_NAME, 'Streams are not supported!')); return cb(); } if (file.isBuffer()) { file.contents = Buffer.concat([prefixText, file.contents]); } // make sure the file goes through the next gulp plugin this.push(file); // tell the stream engine that we are done with this file cb(); }); // returning the file stream return stream; }; // exporting the plugin main function module.exports = gulpPrefixer; ``` The above plugin can be used like this: ```js var gulp = require('gulp'); var gulpPrefixer = require('gulp-prefixer'); gulp.src('files/**/*.js') .pipe(gulpPrefixer('prepended string')) .pipe(gulp.dest('modified-files')); ``` ## Handling streams Unfortunately, the above plugin will error when using gulp.src in non-buffered (streaming) mode. You should support streams too if possible. See [Dealing with streams](dealing-with-streams.md) for more information. ## Some plugins based on buffers * [gulp-coffee](https://github.com/wearefractal/gulp-coffee) * [gulp-svgmin](https://github.com/ben-eb/gulp-svgmin) * [gulp-marked](https://github.com/lmtm/gulp-marked) * [gulp-svg2ttf](https://github.com/nfroidure/gulp-svg2ttf) gulp-3.9.1/index.js000066400000000000000000000027621265616124500141570ustar00rootroot00000000000000'use strict'; var util = require('util'); var Orchestrator = require('orchestrator'); var gutil = require('gulp-util'); var deprecated = require('deprecated'); var vfs = require('vinyl-fs'); function Gulp() { Orchestrator.call(this); } util.inherits(Gulp, Orchestrator); Gulp.prototype.task = Gulp.prototype.add; Gulp.prototype.run = function() { // `run()` is deprecated as of 3.5 and will be removed in 4.0 // Use task dependencies instead // Impose our opinion of "default" tasks onto orchestrator var tasks = arguments.length ? arguments : ['default']; this.start.apply(this, tasks); }; Gulp.prototype.src = vfs.src; Gulp.prototype.dest = vfs.dest; Gulp.prototype.watch = function(glob, opt, fn) { if (typeof opt === 'function' || Array.isArray(opt)) { fn = opt; opt = null; } // Array of tasks given if (Array.isArray(fn)) { return vfs.watch(glob, opt, function() { this.start.apply(this, fn); }.bind(this)); } return vfs.watch(glob, opt, fn); }; // Let people use this class from our instance Gulp.prototype.Gulp = Gulp; // Deprecations deprecated.field('gulp.env has been deprecated. ' + 'Use your own CLI parser instead. ' + 'We recommend using yargs or minimist.', console.warn, Gulp.prototype, 'env', gutil.env ); Gulp.prototype.run = deprecated.method('gulp.run() has been deprecated. ' + 'Use task dependencies or gulp.watch task triggering instead.', console.warn, Gulp.prototype.run ); var inst = new Gulp(); module.exports = inst; gulp-3.9.1/lib/000077500000000000000000000000001265616124500132515ustar00rootroot00000000000000gulp-3.9.1/lib/completion.js000066400000000000000000000007431265616124500157640ustar00rootroot00000000000000'use strict'; var fs = require('fs'); var path = require('path'); module.exports = function(name) { if (typeof name !== 'string') { throw new Error('Missing completion type'); } var file = path.join(__dirname, '../completion', name); try { console.log(fs.readFileSync(file, 'utf8')); process.exit(0); } catch (err) { console.log( 'echo "gulp autocompletion rules for', '\'' + name + '\'', 'not found"' ); process.exit(5); } }; gulp-3.9.1/lib/taskTree.js000066400000000000000000000004001265616124500153630ustar00rootroot00000000000000'use strict'; module.exports = function(tasks) { return Object.keys(tasks) .reduce(function(prev, task) { prev.nodes.push({ label: task, nodes: tasks[task].dep, }); return prev; }, { nodes: [], }); }; gulp-3.9.1/package.json000066400000000000000000000031731265616124500147750ustar00rootroot00000000000000{ "name": "gulp", "description": "The streaming build system", "version": "3.9.1", "homepage": "http://gulpjs.com", "repository": "gulpjs/gulp", "author": "Fractal (http://wearefractal.com/)", "tags": [ "build", "stream", "system", "make", "tool", "asset", "pipeline" ], "files": [ "index.js", "lib", "bin", "completion", "gulp.1" ], "bin": { "gulp": "./bin/gulp.js" }, "man": "gulp.1", "dependencies": { "archy": "^1.0.0", "chalk": "^1.0.0", "deprecated": "^0.0.1", "gulp-util": "^3.0.0", "interpret": "^1.0.0", "liftoff": "^2.1.0", "minimist": "^1.1.0", "orchestrator": "^0.3.0", "pretty-hrtime": "^1.0.0", "semver": "^4.1.0", "tildify": "^1.0.0", "v8flags": "^2.0.2", "vinyl-fs": "^0.3.0" }, "devDependencies": { "coveralls": "^2.7.0", "eslint": "^1.7.3", "eslint-config-gulp": "^2.0.0", "graceful-fs": "^3.0.0", "istanbul": "^0.3.0", "jscs": "^2.3.5", "jscs-preset-gulp": "^1.0.0", "marked-man": "^0.1.3", "mkdirp": "^0.5.0", "mocha": "^2.0.1", "mocha-lcov-reporter": "^0.0.1", "q": "^1.0.0", "rimraf": "^2.2.5", "should": "^5.0.1" }, "scripts": { "prepublish": "marked-man --name gulp docs/CLI.md > gulp.1", "lint": "eslint . && jscs *.js bin/ lib/ test/", "pretest": "npm run lint", "test": "mocha --reporter spec", "coveralls": "istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage" }, "engines": { "node": ">= 0.9" }, "license": "MIT" } gulp-3.9.1/test/000077500000000000000000000000001265616124500134625ustar00rootroot00000000000000gulp-3.9.1/test/.eslintrc000066400000000000000000000000351265616124500153040ustar00rootroot00000000000000{ "extends": "gulp/test" } gulp-3.9.1/test/dest.js000066400000000000000000000110041265616124500147530ustar00rootroot00000000000000'use strict'; var gulp = require('../'); var should = require('should'); var join = require('path').join; var rimraf = require('rimraf'); var fs = require('graceful-fs'); require('mocha'); var outpath = join(__dirname, './out-fixtures'); describe('gulp output stream', function() { describe('dest()', function() { beforeEach(rimraf.bind(null, outpath)); afterEach(rimraf.bind(null, outpath)); it('should return a stream', function(done) { var stream = gulp.dest(join(__dirname, './fixtures/')); should.exist(stream); should.exist(stream.on); done(); }); it('should return a output stream that writes files', function(done) { var instream = gulp.src(join(__dirname, './fixtures/**/*.txt')); var outstream = gulp.dest(outpath); instream.pipe(outstream); outstream.on('error', done); outstream.on('data', function(file) { // Data should be re-emitted right should.exist(file); should.exist(file.path); should.exist(file.contents); join(file.path, '').should.equal(join(outpath, './copy/example.txt')); String(file.contents).should.equal('this is a test'); }); outstream.on('end', function() { fs.readFile(join(outpath, 'copy', 'example.txt'), function(err, contents) { should.not.exist(err); should.exist(contents); String(contents).should.equal('this is a test'); done(); }); }); }); it('should return a output stream that does not write non-read files', function(done) { var instream = gulp.src(join(__dirname, './fixtures/**/*.txt'), { read: false }); var outstream = gulp.dest(outpath); instream.pipe(outstream); outstream.on('error', done); outstream.on('data', function(file) { // Data should be re-emitted right should.exist(file); should.exist(file.path); should.not.exist(file.contents); join(file.path, '').should.equal(join(outpath, './copy/example.txt')); }); outstream.on('end', function() { fs.readFile(join(outpath, 'copy', 'example.txt'), function(err, contents) { should.exist(err); should.not.exist(contents); done(); }); }); }); it('should return a output stream that writes streaming files', function(done) { var instream = gulp.src(join(__dirname, './fixtures/**/*.txt'), { buffer: false }); var outstream = instream.pipe(gulp.dest(outpath)); outstream.on('error', done); outstream.on('data', function(file) { // Data should be re-emitted right should.exist(file); should.exist(file.path); should.exist(file.contents); join(file.path, '').should.equal(join(outpath, './copy/example.txt')); }); outstream.on('end', function() { fs.readFile(join(outpath, 'copy', 'example.txt'), function(err, contents) { should.not.exist(err); should.exist(contents); String(contents).should.equal('this is a test'); done(); }); }); }); it('should return a output stream that writes streaming files into new directories', function(done) { testWriteDir({}, done); }); it('should return a output stream that writes streaming files into new directories (buffer: false)', function(done) { testWriteDir({ buffer: false }, done); }); it('should return a output stream that writes streaming files into new directories (read: false)', function(done) { testWriteDir({ read: false }, done); }); it('should return a output stream that writes streaming files into new directories (read: false, buffer: false)', function(done) { testWriteDir({ buffer: false, read: false }, done); }); function testWriteDir(srcOptions, done) { var instream = gulp.src(join(__dirname, './fixtures/stuff'), srcOptions); var outstream = instream.pipe(gulp.dest(outpath)); outstream.on('error', done); outstream.on('data', function(file) { // Data should be re-emitted right should.exist(file); should.exist(file.path); join(file.path, '').should.equal(join(outpath, './stuff')); }); outstream.on('end', function() { fs.exists(join(outpath, 'stuff'), function(exists) { /* Stinks that ok is an expression instead of a function call */ /* jshint expr: true */ should(exists).be.ok; /* jshint expr: false */ done(); }); }); } }); }); gulp-3.9.1/test/fixtures/000077500000000000000000000000001265616124500153335ustar00rootroot00000000000000gulp-3.9.1/test/fixtures/copy/000077500000000000000000000000001265616124500163055ustar00rootroot00000000000000gulp-3.9.1/test/fixtures/copy/example.txt000066400000000000000000000000161265616124500204760ustar00rootroot00000000000000this is a testgulp-3.9.1/test/fixtures/stuff/000077500000000000000000000000001265616124500164625ustar00rootroot00000000000000gulp-3.9.1/test/fixtures/stuff/run.dmc000066400000000000000000000000001265616124500177410ustar00rootroot00000000000000gulp-3.9.1/test/fixtures/stuff/test.dmc000066400000000000000000000000001265616124500201140ustar00rootroot00000000000000gulp-3.9.1/test/fixtures/test.coffee000066400000000000000000000000161265616124500174600ustar00rootroot00000000000000this is a testgulp-3.9.1/test/fixtures/test/000077500000000000000000000000001265616124500163125ustar00rootroot00000000000000gulp-3.9.1/test/fixtures/test/run.jade000066400000000000000000000000151265616124500177370ustar00rootroot00000000000000test templategulp-3.9.1/test/src.js000066400000000000000000000116121265616124500146100ustar00rootroot00000000000000'use strict'; var gulp = require('../'); var should = require('should'); var join = require('path').join; require('mocha'); describe('gulp input stream', function() { describe('src()', function() { it('should return a stream', function(done) { var stream = gulp.src(join(__dirname, './fixtures/*.coffee')); should.exist(stream); should.exist(stream.on); done(); }); it('should return a input stream from a flat glob', function(done) { var stream = gulp.src(join(__dirname, './fixtures/*.coffee')); stream.on('error', done); stream.on('data', function(file) { should.exist(file); should.exist(file.path); should.exist(file.contents); join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee')); String(file.contents).should.equal('this is a test'); }); stream.on('end', function() { done(); }); }); it('should return a input stream for multiple globs', function(done) { var globArray = [ join(__dirname, './fixtures/stuff/run.dmc'), join(__dirname, './fixtures/stuff/test.dmc'), ]; var stream = gulp.src(globArray); var files = []; stream.on('error', done); stream.on('data', function(file) { should.exist(file); should.exist(file.path); files.push(file); }); stream.on('end', function() { files.length.should.equal(2); files[0].path.should.equal(globArray[0]); files[1].path.should.equal(globArray[1]); done(); }); }); it('should return a input stream for multiple globs, with negation', function(done) { var expectedPath = join(__dirname, './fixtures/stuff/run.dmc'); var globArray = [ join(__dirname, './fixtures/stuff/*.dmc'), '!' + join(__dirname, './fixtures/stuff/test.dmc'), ]; var stream = gulp.src(globArray); var files = []; stream.on('error', done); stream.on('data', function(file) { should.exist(file); should.exist(file.path); files.push(file); }); stream.on('end', function() { files.length.should.equal(1); files[0].path.should.equal(expectedPath); done(); }); }); it('should return a input stream with no contents when read is false', function(done) { var stream = gulp.src(join(__dirname, './fixtures/*.coffee'), { read: false }); stream.on('error', done); stream.on('data', function(file) { should.exist(file); should.exist(file.path); should.not.exist(file.contents); join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee')); }); stream.on('end', function() { done(); }); }); it('should return a input stream with contents as stream when buffer is false', function(done) { var stream = gulp.src(join(__dirname, './fixtures/*.coffee'), { buffer: false }); stream.on('error', done); stream.on('data', function(file) { should.exist(file); should.exist(file.path); should.exist(file.contents); var buf = ''; file.contents.on('data', function(d) { buf += d; }); file.contents.on('end', function() { buf.should.equal('this is a test'); done(); }); join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee')); }); }); it('should return a input stream from a deep glob', function(done) { var stream = gulp.src(join(__dirname, './fixtures/**/*.jade')); stream.on('error', done); stream.on('data', function(file) { should.exist(file); should.exist(file.path); should.exist(file.contents); join(file.path, '').should.equal(join(__dirname, './fixtures/test/run.jade')); String(file.contents).should.equal('test template'); }); stream.on('end', function() { done(); }); }); it('should return a input stream from a deeper glob', function(done) { var stream = gulp.src(join(__dirname, './fixtures/**/*.dmc')); var a = 0; stream.on('error', done); stream.on('data', function() { ++a; }); stream.on('end', function() { a.should.equal(2); done(); }); }); it('should return a file stream from a flat path', function(done) { var a = 0; var stream = gulp.src(join(__dirname, './fixtures/test.coffee')); stream.on('error', done); stream.on('data', function(file) { ++a; should.exist(file); should.exist(file.path); should.exist(file.contents); join(file.path, '').should.equal(join(__dirname, './fixtures/test.coffee')); String(file.contents).should.equal('this is a test'); }); stream.on('end', function() { a.should.equal(1); done(); }); }); }); }); gulp-3.9.1/test/taskTree.js000066400000000000000000000013331265616124500156020ustar00rootroot00000000000000'use strict'; var taskTree = require('../lib/taskTree'); var should = require('should'); require('mocha'); describe('taskTree()', function() { it('should form a tree properly', function(done) { should.exist(taskTree); // Lol shutup jshint var tasks = { test: { dep: ['abc', 'def'], }, abc: { dep: ['def'], }, def: { dep: [], }, }; var expectTree = { nodes: [ { label: 'test', nodes: ['abc', 'def'], }, { label: 'abc', nodes: ['def'], }, { label: 'def', nodes: [], }, ], }; taskTree(tasks).should.eql(expectTree); done(); }); }); gulp-3.9.1/test/tasks.js000066400000000000000000000073041265616124500151510ustar00rootroot00000000000000'use strict'; var gulp = require('../'); var Q = require('q'); var should = require('should'); require('mocha'); describe('gulp tasks', function() { describe('task()', function() { it('should define a task', function(done) { var fn; fn = function() {}; gulp.task('test', fn); should.exist(gulp.tasks.test); gulp.tasks.test.fn.should.equal(fn); gulp.reset(); done(); }); }); describe('run()', function() { it('should run multiple tasks', function(done) { var a, fn, fn2; a = 0; fn = function() { this.should.equal(gulp); ++a; }; fn2 = function() { this.should.equal(gulp); ++a; }; gulp.task('test', fn); gulp.task('test2', fn2); gulp.run('test', 'test2'); a.should.equal(2); gulp.reset(); done(); }); it('should run all tasks when call run() multiple times', function(done) { var a, fn, fn2; a = 0; fn = function() { this.should.equal(gulp); ++a; }; fn2 = function() { this.should.equal(gulp); ++a; }; gulp.task('test', fn); gulp.task('test2', fn2); gulp.run('test'); gulp.run('test2'); a.should.equal(2); gulp.reset(); done(); }); it('should run all async promise tasks', function(done) { var a, fn, fn2; a = 0; fn = function() { var deferred = Q.defer(); setTimeout(function() { ++a; deferred.resolve(); }, 1); return deferred.promise; }; fn2 = function() { var deferred = Q.defer(); setTimeout(function() { ++a; deferred.resolve(); }, 1); return deferred.promise; }; gulp.task('test', fn); gulp.task('test2', fn2); gulp.run('test'); gulp.run('test2', function() { gulp.isRunning.should.equal(false); a.should.equal(2); gulp.reset(); done(); }); gulp.isRunning.should.equal(true); }); it('should run all async callback tasks', function(done) { var a, fn, fn2; a = 0; fn = function(cb) { setTimeout(function() { ++a; cb(null); }, 1); }; fn2 = function(cb) { setTimeout(function() { ++a; cb(null); }, 1); }; gulp.task('test', fn); gulp.task('test2', fn2); gulp.run('test'); gulp.run('test2', function() { gulp.isRunning.should.equal(false); a.should.equal(2); gulp.reset(); done(); }); gulp.isRunning.should.equal(true); }); it('should emit task_not_found and throw an error when task is not defined', function(done) { gulp.on('task_not_found', function(err) { should.exist(err); should.exist(err.task); err.task.should.equal('test'); gulp.reset(); done(); }); try { gulp.run('test'); } catch (err) { should.exist(err); } }); it('should run task scoped to gulp', function(done) { var a, fn; a = 0; fn = function() { this.should.equal(gulp); ++a; }; gulp.task('test', fn); gulp.run('test'); a.should.equal(1); gulp.isRunning.should.equal(false); gulp.reset(); done(); }); it('should run default task scoped to gulp', function(done) { var a, fn; a = 0; fn = function() { this.should.equal(gulp); ++a; }; gulp.task('default', fn); gulp.run(); a.should.equal(1); gulp.isRunning.should.equal(false); gulp.reset(); done(); }); }); }); gulp-3.9.1/test/watch.js000066400000000000000000000121341265616124500151270ustar00rootroot00000000000000'use strict'; var gulp = require('../'); var fs = require('graceful-fs'); var rimraf = require('rimraf'); var mkdirp = require('mkdirp'); var path = require('path'); var should = require('should'); require('mocha'); var outpath = path.join(__dirname, './out-fixtures'); describe('gulp', function() { describe('watch()', function() { beforeEach(rimraf.bind(null, outpath)); beforeEach(mkdirp.bind(null, outpath)); afterEach(rimraf.bind(null, outpath)); var tempFileContent = 'A test generated this file and it is safe to delete'; var writeTimeout = 125; // Wait for it to get to the filesystem var writeFileWait = function(name, content, cb) { if (!cb) { cb = function() {}; } setTimeout(function() { fs.writeFile(name, content, cb); }, writeTimeout); }; it('should call the function when file changes: no options', function(done) { // Arrange var tempFile = path.join(outpath, 'watch-func.txt'); fs.writeFile(tempFile, tempFileContent, function() { // Assert: it works if it calls done var watcher = gulp.watch(tempFile, function(evt) { should.exist(evt); should.exist(evt.path); should.exist(evt.type); evt.type.should.equal('changed'); evt.path.should.equal(path.resolve(tempFile)); watcher.end(); done(); }); // Act: change file writeFileWait(tempFile, tempFileContent + ' changed'); }); }); it('should call the function when file changes: w/ options', function(done) { // Arrange var tempFile = path.join(outpath, 'watch-func-options.txt'); fs.writeFile(tempFile, tempFileContent, function() { // Assert: it works if it calls done var watcher = gulp.watch(tempFile, { debounceDelay: 5 }, function(evt) { should.exist(evt); should.exist(evt.path); should.exist(evt.type); evt.type.should.equal('changed'); evt.path.should.equal(path.resolve(tempFile)); watcher.end(); done(); }); // Act: change file writeFileWait(tempFile, tempFileContent + ' changed'); }); }); it('should not drop options when no callback specified', function(done) { // Arrange var tempFile = path.join(outpath, 'watch-func-nodrop-options.txt'); // By passing a cwd option, ensure options are not lost to gaze var relFile = '../watch-func-nodrop-options.txt'; var cwd = outpath + '/subdir'; fs.writeFile(tempFile, tempFileContent, function() { // Assert: it works if it calls done var watcher = gulp.watch(relFile, { debounceDelay: 5, cwd: cwd }) .on('change', function(evt) { should.exist(evt); should.exist(evt.path); should.exist(evt.type); evt.type.should.equal('changed'); evt.path.should.equal(path.resolve(tempFile)); watcher.end(); done(); }); // Act: change file writeFileWait(tempFile, tempFileContent + ' changed'); }); }); it('should run many tasks: w/ options', function(done) { // Arrange var tempFile = path.join(outpath, 'watch-task-options.txt'); var task1 = 'task1'; var task2 = 'task2'; var task3 = 'task3'; var a = 0; var timeout = writeTimeout * 2.5; fs.writeFile(tempFile, tempFileContent, function() { gulp.task(task1, function() { a++; }); gulp.task(task2, function() { a += 10; }); gulp.task(task3, function() { throw new Error('task3 called!'); }); // It works if it calls the task var config = { debounceDelay: timeout / 2 }; var watcher = gulp.watch(tempFile, config, [task1, task2]); // Assert setTimeout(function() { a.should.equal(11); // Task1 and task2 gulp.reset(); watcher.end(); done(); }, timeout); // Act: change file writeFileWait(tempFile, tempFileContent + ' changed'); }); }); it('should run many tasks: no options', function(done) { // Arrange var tempFile = path.join(outpath, 'watch-many-tasks-no-options.txt'); var task1 = 'task1'; var task2 = 'task2'; var task3 = 'task3'; var a = 0; var timeout = writeTimeout * 2.5; fs.writeFile(tempFile, tempFileContent, function() { gulp.task(task1, function() { a++; }); gulp.task(task2, function() { a += 10; }); gulp.task(task3, function() { throw new Error('task3 called!'); }); // It works if it calls the task var watcher = gulp.watch(tempFile, [task1, task2]); // Assert setTimeout(function() { a.should.equal(11); // Task1 and task2 gulp.reset(); watcher.end(); done(); }, timeout); // Act: change file writeFileWait(tempFile, tempFileContent + ' changed'); }); }); }); });