pax_global_header 0000666 0000000 0000000 00000000064 12656161245 0014522 g ustar 00root root 0000000 0000000 52 comment=9c14e3a13a73a32e424f144d62566671b2fcdbed
gulp-3.9.1/ 0000775 0000000 0000000 00000000000 12656161245 0012503 5 ustar 00root root 0000000 0000000 gulp-3.9.1/.editorconfig 0000664 0000000 0000000 00000000317 12656161245 0015161 0 ustar 00root root 0000000 0000000 # 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/.eslintrc 0000664 0000000 0000000 00000000030 12656161245 0014320 0 ustar 00root root 0000000 0000000 {
"extends": "gulp"
}
gulp-3.9.1/.gitignore 0000664 0000000 0000000 00000000177 12656161245 0014500 0 ustar 00root root 0000000 0000000 .DS_Store
*.log
node_modules
build
*.node
components
coverage
*.orig
.idea
sandbox
test/out-fixtures/*
test/watch-*.txt
gulp.1
gulp-3.9.1/.jscsrc 0000664 0000000 0000000 00000000030 12656161245 0013764 0 ustar 00root root 0000000 0000000 {
"preset": "gulp",
}
gulp-3.9.1/.npmignore 0000664 0000000 0000000 00000000170 12656161245 0014500 0 ustar 00root root 0000000 0000000 .DS_Store
*.log
node_modules
build
*.node
components
coverage
*.orig
.idea
sandbox
test/out-fixtures/*
test/watch-*.txt
gulp-3.9.1/.travis.yml 0000664 0000000 0000000 00000000207 12656161245 0014613 0 ustar 00root root 0000000 0000000 sudo: 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.md 0000664 0000000 0000000 00000013122 12656161245 0014313 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000007164 12656161245 0014744 0 ustar 00root root 0000000 0000000 # 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/LICENSE 0000664 0000000 0000000 00000002122 12656161245 0013505 0 ustar 00root root 0000000 0000000 The 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.md 0000664 0000000 0000000 00000007570 12656161245 0013773 0 ustar 00root root 0000000 0000000
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/ 0000775 0000000 0000000 00000000000 12656161245 0013253 5 ustar 00root root 0000000 0000000 gulp-3.9.1/bin/gulp.js 0000775 0000000 0000000 00000012410 12656161245 0014561 0 ustar 00root root 0000000 0000000 #!/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/ 0000775 0000000 0000000 00000000000 12656161245 0014654 5 ustar 00root root 0000000 0000000 gulp-3.9.1/completion/README.md 0000664 0000000 0000000 00000001000 12656161245 0016122 0 ustar 00root root 0000000 0000000 # 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/bash 0000664 0000000 0000000 00000001336 12656161245 0015517 0 ustar 00root root 0000000 0000000 #!/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/fish 0000664 0000000 0000000 00000000342 12656161245 0015527 0 ustar 00root root 0000000 0000000 #!/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/powershell 0000664 0000000 0000000 00000003600 12656161245 0016762 0 ustar 00root root 0000000 0000000 # 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/zsh 0000664 0000000 0000000 00000001121 12656161245 0015376 0 ustar 00root root 0000000 0000000 #!/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/ 0000775 0000000 0000000 00000000000 12656161245 0013433 5 ustar 00root root 0000000 0000000 gulp-3.9.1/docs/API.md 0000664 0000000 0000000 00000020553 12656161245 0014373 0 ustar 00root root 0000000 0000000 ## 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.md 0000664 0000000 0000000 00000003405 12656161245 0014366 0 ustar 00root root 0000000 0000000 ## 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.md 0000664 0000000 0000000 00000003357 12656161245 0014374 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000005577 12656161245 0014730 0 ustar 00root root 0000000 0000000 # 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)*.
[](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.md 0000664 0000000 0000000 00000002253 12656161245 0017064 0 ustar 00root root 0000000 0000000 # 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/ 0000775 0000000 0000000 00000000000 12656161245 0015065 5 ustar 00root root 0000000 0000000 gulp-3.9.1/docs/recipes/README.md 0000664 0000000 0000000 00000003206 12656161245 0016345 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000005272 12656161245 0022522 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000002522 12656161245 0021777 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000002423 12656161245 0023074 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000004426 12656161245 0021665 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000001674 12656161245 0024223 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000004264 12656161245 0021230 0 ustar 00root root 0000000 0000000
# 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.md 0000664 0000000 0000000 00000000553 12656161245 0020642 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000004166 12656161245 0024611 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000002242 12656161245 0024046 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000003431 12656161245 0024424 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000002603 12656161245 0026137 0 ustar 00root root 0000000 0000000 # 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

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

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

gulp-3.9.1/docs/recipes/make-stream-from-buffer.md 0000664 0000000 0000000 00000010501 12656161245 0022022 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000001256 12656161245 0022311 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000001477 12656161245 0022711 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000001607 12656161245 0023505 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000001221 12656161245 0022062 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000000543 12656161245 0023277 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000003450 12656161245 0023222 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000004542 12656161245 0022113 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000005405 12656161245 0025324 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000003757 12656161245 0024751 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000000736 12656161245 0020546 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000001047 12656161245 0024110 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000001453 12656161245 0025616 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000001500 12656161245 0022530 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000001321 12656161245 0024166 0 ustar 00root root 0000000 0000000 # 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/ 0000775 0000000 0000000 00000000000 12656161245 0016630 5 ustar 00root root 0000000 0000000 gulp-3.9.1/docs/writing-a-plugin/README.md 0000664 0000000 0000000 00000017164 12656161245 0020120 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000004400 12656161245 0023200 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000013261 12656161245 0021305 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000001126 12656161245 0023102 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000005125 12656161245 0020632 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000004104 12656161245 0021730 0 ustar 00root root 0000000 0000000 # 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.js 0000664 0000000 0000000 00000002762 12656161245 0014157 0 ustar 00root root 0000000 0000000 '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/ 0000775 0000000 0000000 00000000000 12656161245 0013251 5 ustar 00root root 0000000 0000000 gulp-3.9.1/lib/completion.js 0000664 0000000 0000000 00000000743 12656161245 0015764 0 ustar 00root root 0000000 0000000 '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.js 0000664 0000000 0000000 00000000400 12656161245 0015363 0 ustar 00root root 0000000 0000000 '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.json 0000664 0000000 0000000 00000003173 12656161245 0014775 0 ustar 00root root 0000000 0000000 {
"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/ 0000775 0000000 0000000 00000000000 12656161245 0013462 5 ustar 00root root 0000000 0000000 gulp-3.9.1/test/.eslintrc 0000664 0000000 0000000 00000000035 12656161245 0015304 0 ustar 00root root 0000000 0000000 {
"extends": "gulp/test"
}
gulp-3.9.1/test/dest.js 0000664 0000000 0000000 00000011004 12656161245 0014753 0 ustar 00root root 0000000 0000000 '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/ 0000775 0000000 0000000 00000000000 12656161245 0015333 5 ustar 00root root 0000000 0000000 gulp-3.9.1/test/fixtures/copy/ 0000775 0000000 0000000 00000000000 12656161245 0016305 5 ustar 00root root 0000000 0000000 gulp-3.9.1/test/fixtures/copy/example.txt 0000664 0000000 0000000 00000000016 12656161245 0020476 0 ustar 00root root 0000000 0000000 this is a test gulp-3.9.1/test/fixtures/stuff/ 0000775 0000000 0000000 00000000000 12656161245 0016462 5 ustar 00root root 0000000 0000000 gulp-3.9.1/test/fixtures/stuff/run.dmc 0000664 0000000 0000000 00000000000 12656161245 0017741 0 ustar 00root root 0000000 0000000 gulp-3.9.1/test/fixtures/stuff/test.dmc 0000664 0000000 0000000 00000000000 12656161245 0020114 0 ustar 00root root 0000000 0000000 gulp-3.9.1/test/fixtures/test.coffee 0000664 0000000 0000000 00000000016 12656161245 0017460 0 ustar 00root root 0000000 0000000 this is a test gulp-3.9.1/test/fixtures/test/ 0000775 0000000 0000000 00000000000 12656161245 0016312 5 ustar 00root root 0000000 0000000 gulp-3.9.1/test/fixtures/test/run.jade 0000664 0000000 0000000 00000000015 12656161245 0017737 0 ustar 00root root 0000000 0000000 test template gulp-3.9.1/test/src.js 0000664 0000000 0000000 00000011612 12656161245 0014610 0 ustar 00root root 0000000 0000000 '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.js 0000664 0000000 0000000 00000001333 12656161245 0015602 0 ustar 00root root 0000000 0000000 '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.js 0000664 0000000 0000000 00000007304 12656161245 0015151 0 ustar 00root root 0000000 0000000 '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.js 0000664 0000000 0000000 00000012134 12656161245 0015127 0 ustar 00root root 0000000 0000000 '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');
});
});
});
});