diff --git a/README.md b/README.md index 8fb4d76d..d711f58c 100644 --- a/README.md +++ b/README.md @@ -61,21 +61,8 @@ fs.src(['*.js', '!b*.js']) #### Options -##### `options.cwd` - -The working directory the folder is relative to. - -Type: `String` - -Default: `process.cwd()` - -##### `options.base` - -The folder relative to the cwd. This is used to determine the file names when saving in `.dest()`. - -Type: `String` - -Default: The part of the path before the glob (if any) begins. For example, `path/to/**/*.js` would resolve to `path/to`. If there is no glob (i.e. a file path with no pattern), then the dirname of the path is used. For example, `path/to/some/file.js` would resolve to `path/to/some`. +- Values passed to the options must be of the right type, otherwise they will be ignored. +- All options can be passed a function instead of a value. The function must return a value of the right type, otherwise it will be ignored. ##### `options.buffer` @@ -145,6 +132,7 @@ Default: `false` Any glob-related options are documented in [glob-stream] and [node-glob]. Any through2-related options are documented in [through2]. +Those options are forwarded verbatim. ### `dest(folder[, options])` @@ -165,6 +153,9 @@ __Note: The file will be modified after being written to this stream.__ #### Options +- Values passed to the options must be of the right type, otherwise they will be ignored. +- All options can be passed a function instead of a value. The function will be called with the [vinyl] `File` object as its only argument and must return a value of the right type for the option. + ##### `options.cwd` The working directory the folder is relative to. @@ -240,6 +231,7 @@ Default: `undefined` (do not write sourcemaps) ##### other Any through2-related options are documented in [through2]. +Those options are forwarded verbatim. ### `symlink(folder[, options])` @@ -251,6 +243,9 @@ __Note: The file will be modified after being written to this stream.__ #### Options +- Values passed to the options must be of the right type, otherwise they will be ignored. +- All options can be passed a function instead of a value. The function will be called with the [vinyl] `File` object as its only argument and must return a value of the right type for the option. + ##### `options.cwd` The working directory the folder is relative to. @@ -278,6 +273,7 @@ Default: The process mode. ##### other Any through2-related options are documented in [through2]. +Those options are forwarded verbatim. [glob-stream]: https://github.com/gulpjs/glob-stream [gulp-sourcemaps]: https://github.com/floridoo/gulp-sourcemaps diff --git a/lib/default-value.js b/lib/default-value.js new file mode 100644 index 00000000..07eaa0eb --- /dev/null +++ b/lib/default-value.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function defaultValue(defaultValue, value) { + return value === null ? defaultValue : value; +}; diff --git a/lib/dest/index.js b/lib/dest/index.js index a25d316f..776d4a48 100644 --- a/lib/dest/index.js +++ b/lib/dest/index.js @@ -3,6 +3,8 @@ var through2 = require('through2'); var sourcemaps = require('gulp-sourcemaps'); var duplexify = require('duplexify'); +var valueOrFunction = require('value-or-function'); + var sink = require('../sink'); var prepareWrite = require('../prepare-write'); var writeContents = require('./write-contents'); @@ -12,6 +14,9 @@ function dest(outFolder, opt) { opt = {}; } + var sourcemapsOpt = valueOrFunction( + ['boolean', 'string', 'object'], opt.sourcemaps); + function saveFile(file, enc, cb) { prepareWrite(outFolder, file, opt, function(err, writePath) { if (err) { @@ -22,7 +27,7 @@ function dest(outFolder, opt) { } var saveStream = through2.obj(opt, saveFile); - if (!opt.sourcemaps) { + if (!sourcemapsOpt) { // Sink the save stream to start flowing // Do this on nextTick, it will flow at slowest speed of piped streams process.nextTick(sink(saveStream)); @@ -30,17 +35,15 @@ function dest(outFolder, opt) { return saveStream; } - var sourcemapOpt = opt.sourcemaps; - if (typeof sourcemapOpt === 'boolean') { - sourcemapOpt = {}; - } - if (typeof sourcemapOpt === 'string') { - sourcemapOpt = { - path: sourcemapOpt, + if (typeof sourcemapsOpt === 'boolean') { + sourcemapsOpt = {}; + } else if (typeof sourcemapsOpt === 'string') { + sourcemapsOpt = { + path: sourcemapsOpt, }; } - var mapStream = sourcemaps.write(sourcemapOpt.path, sourcemapOpt); + var mapStream = sourcemaps.write(sourcemapsOpt.path, sourcemapsOpt); var outputStream = duplexify.obj(mapStream, saveStream); mapStream.pipe(saveStream); diff --git a/lib/prepare-write.js b/lib/prepare-write.js index 50d86cd1..e6f2aa89 100644 --- a/lib/prepare-write.js +++ b/lib/prepare-write.js @@ -5,39 +5,34 @@ var path = require('path'); var mkdirp = require('mkdirp'); var fs = require('graceful-fs'); -function booleanOrFunc(v, file) { - if (typeof v !== 'boolean' && typeof v !== 'function') { - return null; - } +var valueOrFunction = require('value-or-function'); +var defaultValue = require('./default-value'); - return typeof v === 'boolean' ? v : v(file); -} +var boolean = valueOrFunction.boolean; +var number = valueOrFunction.number; +var string = valueOrFunction.string; -function stringOrFunc(v, file) { - if (typeof v !== 'string' && typeof v !== 'function') { - return null; +function prepareWrite(outFolder, file, opt, cb) { + if (!opt) { + opt = {}; } - return typeof v === 'string' ? v : v(file); -} - -function prepareWrite(outFolder, file, opt, cb) { - var options = assign({ - cwd: process.cwd(), - mode: (file.stat ? file.stat.mode : null), - dirMode: null, - overwrite: true, - }, opt); - var overwrite = booleanOrFunc(options.overwrite, file); - options.flag = (overwrite ? 'w' : 'wx'); + var defaultMode = file.stat ? file.stat.mode : null; + var options = assign({}, opt, { + cwd: defaultValue(process.cwd(), string(opt.cwd, file)), + base: string(opt.base, file), + mode: defaultValue(defaultMode, number(opt.mode, file)), + dirMode: number(opt.dirMode, file), + overwrite: defaultValue(true, boolean(opt.overwrite, file)), + }); + options.flag = (options.overwrite ? 'w' : 'wx'); var cwd = path.resolve(options.cwd); - var outFolderPath = stringOrFunc(outFolder, file); + var outFolderPath = string(outFolder, file); if (!outFolderPath) { throw new Error('Invalid output folder'); } - var basePath = options.base ? - stringOrFunc(options.base, file) : path.resolve(cwd, outFolderPath); + var basePath = options.base || path.resolve(cwd, outFolderPath); if (!basePath) { throw new Error('Invalid base option'); } diff --git a/lib/src/index.js b/lib/src/index.js index 9da0c265..6844c314 100644 --- a/lib/src/index.js +++ b/lib/src/index.js @@ -6,21 +6,31 @@ var gs = require('glob-stream'); var duplexify = require('duplexify'); var merge = require('merge-stream'); var sourcemaps = require('gulp-sourcemaps'); -var filterSince = require('../filter-since'); var isValidGlob = require('is-valid-glob'); +var valueOrFunction = require('value-or-function'); +var defaultValue = require('../default-value'); +var filterSince = require('../filter-since'); var getContents = require('./get-contents'); var wrapWithVinylFile = require('./wrap-with-vinyl-file'); +var boolean = valueOrFunction.boolean; +var date = valueOrFunction.date; + function src(glob, opt) { - var options = assign({ - read: true, - buffer: true, - stripBOM: true, - sourcemaps: false, - passthrough: false, - followSymlinks: true, - }, opt); + if (!opt) { + opt = {}; + } + + var options = assign({}, opt, { + buffer: defaultValue(true, boolean(opt.buffer)), + read: defaultValue(true, boolean(opt.read)), + since: date(opt.since), + stripBOM: defaultValue(true, boolean(opt.stripBOM)), + sourcemaps: defaultValue(false, boolean(opt.sourcemaps)), + passthrough: defaultValue(false, boolean(opt.passthrough)), + followSymlinks: defaultValue(true, boolean(opt.followSymlinks)), + }); // Don't pass `read` option on to through2 var read = options.read !== false; diff --git a/package.json b/package.json index cca6081b..8fd853a4 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "through2": "^2.0.0", "through2-filter": "^2.0.0", "vali-date": "^1.0.0", + "value-or-function": "^1.2.0", "vinyl": "^1.0.0" }, "devDependencies": { diff --git a/test/default-value.js b/test/default-value.js new file mode 100644 index 00000000..cabd036d --- /dev/null +++ b/test/default-value.js @@ -0,0 +1,21 @@ +'use strict'; + +var expect = require('expect'); + +var defaultValue = require('../lib/default-value'); + +describe('defaultVaule', function() { + + it('returns the value if the value is not null', function() { + expect(defaultValue('defaultValue', 1)).toBe(1); + }); + + it('returns the value if the value is undefined', function() { + expect(defaultValue('defaultValue', undefined)).toBe(undefined); + }); + + it('returns the default value if the value is null', function() { + expect(defaultValue('defaultValue', null)).toBe('defaultValue'); + }); + +}); diff --git a/test/src.js b/test/src.js index 1601e17f..251425e1 100644 --- a/test/src.js +++ b/test/src.js @@ -398,10 +398,8 @@ describe('source stream', function() { it('should not pass options.read on to through2', function(done) { // Note: https://github.com/gulpjs/vinyl-fs/issues/153 - // In future, if/when function values are supported for options like - // `read` and `buffered`, the expected value here will be 1. var canary = 0; - var expected = 0; + var expected = 1; var read = function() { canary++; return 0;