/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var nsfw = require('nsfw'); var path = require('path'); var fs = require('fs'); var File = require('vinyl'); var es = require('event-stream'); var filter = require('gulp-filter'); function toChangeType(type) { switch (type) { case 0: return 'add'; case 1: return 'unlink'; case 2: return 'change'; } } function watch(root) { var result = es.through(); function handleEvent(path, type) { if (/[/\\].git[/\\]/.test(path) || /[/\\]out[/\\]/.test(path)) { return; // filter as early as possible } var file = new File({ path: path, base: root }); file.event = type; result.emit('data', file); } nsfw(root, function(events) { for (var i = 0; i < events.length; i++) { var e = events[i]; var changeType = e.action; if (changeType === 3 /* RENAMED */) { handleEvent(path.join(e.directory, e.oldFile), 'unlink'); handleEvent(path.join(e.directory, e.newFile), 'add'); } else { handleEvent(path.join(e.directory, e.file), toChangeType(changeType)); } } }).then(function(watcher) { watcher.start(); }); return result; } var cache = Object.create(null); module.exports = function(pattern, options) { options = options || {}; var cwd = path.normalize(options.cwd || process.cwd()); var watcher = cache[cwd]; if (!watcher) { watcher = cache[cwd] = watch(cwd); } var rebase = !options.base ? es.through() : es.mapSync(function(f) { f.base = options.base; return f; }); return watcher .pipe(filter(['**', '!.git{,/**}'])) // ignore all things git .pipe(filter(pattern)) .pipe(es.map(function(file, cb) { fs.stat(file.path, function(err, stat) { if (err && err.code === 'ENOENT') { return cb(null, file); } if (err) { return cb(); } if (!stat.isFile()) { return cb(); } fs.readFile(file.path, function(err, contents) { if (err && err.code === 'ENOENT') { return cb(null, file); } if (err) { return cb(); } file.contents = contents; file.stat = stat; cb(null, file); }); }); })) .pipe(rebase); };