├── .jshintignore ├── .travis.yml ├── .gitignore ├── .npmignore ├── test ├── fixtures │ └── fakefile.js ├── nofile.js ├── boolean.js ├── string.js ├── function.js ├── else.js ├── regex.js ├── array.js └── fileStat.js ├── .jshintrc ├── package.json ├── LICENSE ├── index.js └── README.md /.jshintignore: -------------------------------------------------------------------------------- 1 | node_modules/** 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" 4 | - "10" 5 | - "12" 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | node_modules 4 | build 5 | *.node 6 | components 7 | *.orig 8 | .idea 9 | temp.txt* 10 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | node_modules 4 | build 5 | *.node 6 | components 7 | *.orig 8 | .idea 9 | temp.txt* 10 | test 11 | -------------------------------------------------------------------------------- /test/fixtures/fakefile.js: -------------------------------------------------------------------------------- 1 | /*jshint node:true */ 2 | 3 | "use strict"; 4 | 5 | module.exports = function (path) { 6 | return { 7 | relative: path 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "bitwise": true, 3 | "camelcase": true, 4 | "curly": true, 5 | "eqeqeq": true, 6 | "forin": true, 7 | "immed": true, 8 | "latedef": true, 9 | "newcap": true, 10 | "noarg": true, 11 | "noempty": true, 12 | "nonew": true, 13 | "regexp": true, 14 | "strict": true, 15 | "trailing": true, 16 | "undef": true, 17 | "unused": "strict", 18 | "node": true 19 | } 20 | -------------------------------------------------------------------------------- /test/nofile.js: -------------------------------------------------------------------------------- 1 | /*global describe:false, it:false */ 2 | 3 | 'use strict'; 4 | 5 | var gulpmatch = require('../'); 6 | var should = require('should'); 7 | 8 | describe('gulp-match', function() { 9 | describe('when not given a file,', function() { 10 | it('should throw', function() { 11 | // arrange 12 | var actualErr; 13 | 14 | // act 15 | try { 16 | gulpmatch(); 17 | } catch (err) { 18 | actualErr = err; 19 | } 20 | 21 | // assert 22 | should.exist(actualErr); 23 | actualErr.message.indexOf('file').should.be.above(-1); 24 | actualErr.message.indexOf('require').should.be.above(-1); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gulp-match", 3 | "description": "Does a vinyl file match a condition?", 4 | "version": "1.1.0", 5 | "homepage": "https://github.com/robrich/gulp-match", 6 | "repository": "git://github.com/robrich/gulp-match.git", 7 | "author": "Rob Richardson (http://robrich.org/)", 8 | "main": "./index.js", 9 | "keywords": [ 10 | "gulpfriendly", 11 | "conditional", 12 | "if", 13 | "minimatch" 14 | ], 15 | "dependencies": { 16 | "minimatch": "^3.0.3" 17 | }, 18 | "devDependencies": { 19 | "jshint": "^2.9.4", 20 | "mocha": "^6.1.4", 21 | "should": "^13.2.3" 22 | }, 23 | "scripts": { 24 | "test": "mocha && jshint ." 25 | }, 26 | "license": "MIT" 27 | } 28 | -------------------------------------------------------------------------------- /test/boolean.js: -------------------------------------------------------------------------------- 1 | /*global describe:false, it:false */ 2 | 3 | 'use strict'; 4 | 5 | var gulpmatch = require('../'); 6 | var getFakeFile = require('./fixtures/fakefile'); 7 | require('should'); 8 | 9 | describe('gulp-match', function() { 10 | describe('when given a boolean value,', function() { 11 | it('should return true when passed true', function() { 12 | // arrange 13 | var file = getFakeFile('fake/path.js'); 14 | var expected = true; 15 | 16 | // act 17 | var actual = gulpmatch(file, expected); 18 | 19 | // assert 20 | actual.should.equal(expected); 21 | }); 22 | 23 | it('should return false when passed false', function() { 24 | // arrange 25 | var file = getFakeFile('fake/path.js'); 26 | var expected = false; 27 | 28 | // act 29 | var actual = gulpmatch(file, expected); 30 | 31 | // assert 32 | actual.should.equal(expected); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /test/string.js: -------------------------------------------------------------------------------- 1 | /*global describe:false, it:false */ 2 | 3 | 'use strict'; 4 | 5 | var gulpmatch = require('../'); 6 | var getFakeFile = require('./fixtures/fakefile'); 7 | require('should'); 8 | 9 | describe('gulp-match', function() { 10 | describe('when given a string,', function() { 11 | it('should return true when minimatch matches', function() { 12 | // arrange 13 | var fakePath = 'fake/path.js'; 14 | var file = getFakeFile(fakePath); 15 | var expected = true; 16 | 17 | // act 18 | var actual = gulpmatch(file, fakePath); 19 | 20 | // assert 21 | actual.should.equal(expected); 22 | }); 23 | 24 | it('should return false when passed false', function() { 25 | // arrange 26 | var fakePath = 'fake/path.js'; 27 | var file = getFakeFile('not-fake/path-here.js'); 28 | var expected = false; 29 | 30 | // act 31 | var actual = gulpmatch(file, fakePath); 32 | 33 | // assert 34 | actual.should.equal(expected); 35 | }); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/function.js: -------------------------------------------------------------------------------- 1 | /*global describe:false, it:false */ 2 | 3 | 'use strict'; 4 | 5 | var gulpmatch = require('../'); 6 | var getFakeFile = require('./fixtures/fakefile'); 7 | require('should'); 8 | 9 | describe('gulp-match', function() { 10 | describe('when given a function,', function() { 11 | it('should return true when function returns true', function() { 12 | // arrange 13 | var file = getFakeFile('fake/path.js'); 14 | var expected = true; 15 | var fn = function () { 16 | return true; 17 | }; 18 | 19 | // act 20 | var actual = gulpmatch(file, fn); 21 | 22 | // assert 23 | actual.should.equal(expected); 24 | }); 25 | 26 | it('should return false when function returns false', function() { 27 | // arrange 28 | var file = getFakeFile('fake/path.js'); 29 | var expected = false; 30 | var fn = function () { 31 | return false; 32 | }; 33 | 34 | // act 35 | var actual = gulpmatch(file, fn); 36 | 37 | // assert 38 | actual.should.equal(expected); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 [Richardson & Sons, LLC](http://richardsonandsons.com/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /test/else.js: -------------------------------------------------------------------------------- 1 | /*global describe:false, it:false */ 2 | 3 | 'use strict'; 4 | 5 | var gulpmatch = require('../'); 6 | var getFakeFile = require('./fixtures/fakefile'); 7 | require('should'); 8 | 9 | describe('gulp-match', function() { 10 | describe('when given a non handled value,', function() { 11 | it('should return true when passed truthy', function() { 12 | // arrange 13 | var file = getFakeFile('fake/path.js'); 14 | var expected = true; 15 | var source = 25; 16 | 17 | // act 18 | var actual = gulpmatch(file, source); 19 | 20 | // assert 21 | actual.should.equal(expected); 22 | }); 23 | 24 | it('should return false when passed falsey', function() { 25 | // arrange 26 | var file = getFakeFile('fake/path.js'); 27 | var expected = false; 28 | var source = ''; 29 | 30 | // act 31 | var actual = gulpmatch(file, source); 32 | 33 | // assert 34 | actual.should.equal(expected); 35 | }); 36 | 37 | it('should return false when passed undefined', function() { 38 | // arrange 39 | var file = getFakeFile('fake/path.js'); 40 | var expected = false; 41 | 42 | // act 43 | var actual = gulpmatch(file); 44 | 45 | // assert 46 | actual.should.equal(expected); 47 | }); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /test/regex.js: -------------------------------------------------------------------------------- 1 | /*global describe:false, it:false */ 2 | 3 | 'use strict'; 4 | 5 | var gulpmatch = require('../'); 6 | var getFakeFile = require('./fixtures/fakefile'); 7 | require('should'); 8 | 9 | describe('gulp-match', function() { 10 | describe('when given a regex,', function() { 11 | it('should return true when regex matches', function() { 12 | // arrange 13 | var file = getFakeFile('fake/path.js'); 14 | var regex = /fake\/path\.js/; 15 | var expected = true; 16 | 17 | // act 18 | var actual = gulpmatch(file, regex); 19 | 20 | // assert 21 | actual.should.equal(expected); 22 | }); 23 | 24 | it('should return false when regex doesn\'t match', function() { 25 | // arrange 26 | var file = getFakeFile('fake/path.js'); 27 | var regex = /not\-a\/match\.js/; 28 | var expected = false; 29 | 30 | // act 31 | var actual = gulpmatch(file, regex); 32 | 33 | // assert 34 | actual.should.equal(expected); 35 | }); 36 | 37 | it('should return true when given suffix string matches', function() { 38 | // arrange 39 | var file = getFakeFile('fake/path.js'); 40 | var regex = '*.js'; 41 | var expected = true; 42 | 43 | // act 44 | var actual = gulpmatch(file, regex); 45 | 46 | // assert 47 | actual.should.equal(expected); 48 | }); 49 | 50 | it('should return false when given suffix string doesn\'t match', function() { 51 | // arrange 52 | var file = getFakeFile('fake/path.js'); 53 | var regex = '*.txt'; 54 | var expected = false; 55 | 56 | // act 57 | var actual = gulpmatch(file, regex); 58 | 59 | // assert 60 | actual.should.equal(expected); 61 | }); 62 | 63 | it('should return true when given a complex suffix string', function() { 64 | // arrange 65 | var file = getFakeFile('fake/path.min.less.css'); 66 | var regex = '*.less.css'; 67 | var expected = true; 68 | 69 | // act 70 | var actual = gulpmatch(file, regex); 71 | 72 | // assert 73 | actual.should.equal(expected); 74 | }); 75 | }); 76 | }); 77 | -------------------------------------------------------------------------------- /test/array.js: -------------------------------------------------------------------------------- 1 | /*global describe:false, it:false */ 2 | 3 | 'use strict'; 4 | 5 | var gulpmatch = require('../'); 6 | var getFakeFile = require('./fixtures/fakefile'); 7 | var should = require('should'); 8 | 9 | describe('gulp-match', function() { 10 | describe('when given an array,', function() { 11 | it('should return true when minimatch matches', function() { 12 | // arrange 13 | var fakePath = 'fake/path.js'; 14 | var file = getFakeFile(fakePath); 15 | var expected = true; 16 | 17 | // act 18 | var actual = gulpmatch(file, [fakePath]); 19 | 20 | // assert 21 | actual.should.equal(expected); 22 | }); 23 | 24 | it('should return false when no minimatch matches', function() { 25 | // arrange 26 | var fakePath = 'fake/path.js'; 27 | var file = getFakeFile('not-fake/path-here.js'); 28 | var expected = false; 29 | 30 | // act 31 | var actual = gulpmatch(file, [fakePath]); 32 | 33 | // assert 34 | actual.should.equal(expected); 35 | }); 36 | 37 | it('should throw when passed an empty array', function() { 38 | // arrange 39 | var actualErr; 40 | var file = getFakeFile('not-fake/path-here.js'); 41 | 42 | // act 43 | try { 44 | gulpmatch(file, []); 45 | } catch (err) { 46 | actualErr = err; 47 | } 48 | 49 | // assert 50 | should.exist(actualErr); 51 | actualErr.message.indexOf('array').should.be.above(-1); 52 | actualErr.message.indexOf('empty').should.be.above(-1); 53 | }); 54 | 55 | var multiPatternTest = function (file, expected) { 56 | // arrange 57 | var pattern = ['*', '!*.json', '!*rc']; 58 | 59 | // act 60 | var actual = gulpmatch({relative:file}, pattern); 61 | 62 | // assert 63 | actual.should.equal(expected); 64 | }; 65 | 66 | it('should filter files with negate pattern and leading dot', function() { 67 | multiPatternTest('included.js', true); 68 | multiPatternTest('package.json', false); 69 | multiPatternTest('.jshintrc', false); 70 | multiPatternTest('app.js', true); 71 | }); 72 | 73 | }); 74 | }); 75 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var minimatch = require('minimatch'); 4 | 5 | module.exports = function (file, condition, options) { 6 | if (!file) { 7 | throw new Error('gulp-match: vinyl file required'); 8 | } 9 | 10 | if (typeof condition === 'boolean') { 11 | return condition; 12 | } 13 | 14 | if (typeof condition === 'function') { 15 | return !!condition(file); 16 | } 17 | 18 | if (typeof condition === 'string' && condition.match(/^\*\.[a-z\.]+$/)) { 19 | var newCond = condition.substring(1).replace(/\./g,'\\.')+'$'; 20 | condition = new RegExp(newCond); 21 | } 22 | 23 | if (typeof condition === 'object' && typeof condition.test === 'function' && Object.getPrototypeOf(condition).hasOwnProperty('source')) { 24 | // FRAGILE: ASSUME: it's a regex 25 | return condition.test(file.relative); 26 | } 27 | 28 | if (typeof condition === 'string') { 29 | // FRAGILE: ASSUME: it's a minimatch expression 30 | return minimatch(file.relative, condition, options); 31 | } 32 | 33 | if (Array.isArray(condition)) { 34 | // FRAGILE: ASSUME: it's a minimatch expression 35 | if (!condition.length) { 36 | throw new Error('gulp-match: empty glob array'); 37 | } 38 | var i = 0, step, ret = false; 39 | for (i = 0; i < condition.length; i++) { 40 | step = condition[i]; 41 | if (step[0] === '!') { 42 | if (minimatch(file.relative, step.slice(1), options)) { 43 | return false; 44 | } 45 | } else if (minimatch(file.relative, step, options)) { 46 | ret = true; 47 | } 48 | } 49 | return ret; 50 | } 51 | 52 | if (typeof condition === 'object') { 53 | if (condition.hasOwnProperty('isFile') || condition.hasOwnProperty('isDirectory')) { 54 | if (!file.hasOwnProperty('stat')) { 55 | return false; // TODO: what's a better status? 56 | } 57 | if (condition.hasOwnProperty('isFile')) { 58 | return (condition.isFile === file.stat.isFile()); 59 | } 60 | if (condition.hasOwnProperty('isDirectory')) { 61 | return (condition.isDirectory === file.stat.isDirectory()); 62 | } 63 | } 64 | } 65 | 66 | return !!condition; 67 | }; 68 | -------------------------------------------------------------------------------- /test/fileStat.js: -------------------------------------------------------------------------------- 1 | /*global describe:false, it:false */ 2 | 3 | 'use strict'; 4 | 5 | var gulpmatch = require('../'); 6 | require('should'); 7 | 8 | describe('gulp-match', function() { 9 | describe('when given a file stat object,', function() { 10 | 11 | var getFakeFile = function (path, isFile, isDirectory) { 12 | return { 13 | path: path, 14 | stat: { 15 | isFile: function () { 16 | return isFile; 17 | }, 18 | isDirectory: function () { 19 | return isDirectory; 20 | } 21 | } 22 | }; 23 | }; 24 | 25 | it('should return true when isFile matches', function() { 26 | // arrange 27 | var isFile = true; 28 | var isDirectory = false; 29 | var file = getFakeFile('not-fake/path-here.js', isFile, isDirectory); 30 | var expected = true; 31 | 32 | // act 33 | var actual = gulpmatch(file, {isFile:true}); 34 | 35 | // assert 36 | actual.should.equal(expected); 37 | }); 38 | 39 | it('should return false when isFile doesn\'t match', function() { 40 | // arrange 41 | var isFile = true; 42 | var isDirectory = false; 43 | var file = getFakeFile('not-fake/path-here.js', isFile, isDirectory); 44 | var expected = false; 45 | 46 | // act 47 | var actual = gulpmatch(file, {isFile:false}); 48 | 49 | // assert 50 | actual.should.equal(expected); 51 | }); 52 | 53 | it('should return true when isDirectory matches', function() { 54 | // arrange 55 | var isFile = false; 56 | var isDirectory = true; 57 | var file = getFakeFile('not-fake/path-here.js', isFile, isDirectory); 58 | var expected = true; 59 | 60 | // act 61 | var actual = gulpmatch(file, {isDirectory: true}); 62 | 63 | // assert 64 | actual.should.equal(expected); 65 | }); 66 | 67 | it('should return false when isDirectory doesn\'t match', function() { 68 | // arrange 69 | var isFile = false; 70 | var isDirectory = true; 71 | var file = getFakeFile('not-fake/path-here.js', isFile, isDirectory); 72 | var expected = false; 73 | 74 | // act 75 | var actual = gulpmatch(file, {isDirectory: false}); 76 | 77 | // assert 78 | actual.should.equal(expected); 79 | }); 80 | 81 | it('should return false when file has no stat', function() { 82 | // arrange 83 | var fakePath = 'fake/path.js'; 84 | var file = { 85 | path: fakePath 86 | // no stat 87 | }; 88 | var expected = false; 89 | 90 | // act 91 | var actual = gulpmatch(file, {isFile: true}); 92 | 93 | // assert 94 | actual.should.equal(expected); 95 | }); 96 | }); 97 | }); 98 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | gulp-match ![status](https://secure.travis-ci.org/robrich/gulp-match.png?branch=master) 2 | ========== 3 | 4 | Does a vinyl file match a condition? This function checks the condition on the `file.path` of the 5 | [vinyl-fs](https://github.com/wearefractal/vinyl-fs) file passed to it. 6 | 7 | Condition can be a boolean, a function, a regular expression, a glob string (or array of glob strings), or a stat filter object 8 | 9 | Used by [gulp-if](https://github.com/robrich/gulp-if) and [gulp-ignore](https://github.com/robrich/gulp-ignore) 10 | 11 | ## Usage 12 | 13 | ```javascript 14 | var gulpmatch = require('gulp-match'); 15 | var map = require('map-stream'); 16 | 17 | var condition = true; // TODO: add business logic here 18 | var options = null; // Optionally pass options to minimatch 19 | 20 | vinylfs.src('path/to/file.js') 21 | .pipe(map(function (file, cb) { 22 | var match = gulpmatch(file, condition, options); 23 | if (match) { 24 | // it matched, do stuff 25 | } 26 | cb(null, file); 27 | })); 28 | ``` 29 | 30 | ## API 31 | 32 | ### file 33 | 34 | A [vinyl-fs](https://github.com/wearefractal/vinyl-fs) file. 35 | 36 | ### condition 37 | 38 | #### boolean condition 39 | 40 | ```javascript 41 | var match = gulpmatch(file, true); 42 | ``` 43 | 44 | if the condition parameter is `true` or `false`, results will also be `true` or `false`. 45 | 46 | #### function condition 47 | 48 | ```javascript 49 | var match = gulpmatch(file, function (file) { 50 | return true; 51 | }) 52 | ``` 53 | 54 | if the condition parameter is a function, it will be called, passing in `file` passed to gulp-match. 55 | 56 | #### regular expression condition 57 | 58 | ```javascript 59 | var match = gulpmatch(file, /some\/path\.js/); 60 | ``` 61 | 62 | If the condition is a regular expression, it will be evaluated on the `file.path` passed to gulp-match. 63 | 64 | #### glob condition 65 | 66 | ```javascript 67 | var match = gulpmatch(file, './some/path.js'); 68 | ``` 69 | ```javascript 70 | var match = gulpmatch(file, ['./array','!./of','./globs.js']); 71 | ``` 72 | 73 | The globs are passed to [minimatch](https://github.com/isaacs/minimatch). If the glob matches (or any of the elements in the array match), gulp-match returns `true` else `false`. 74 | 75 | #### stat filter condition 76 | 77 | ```javascript 78 | var match = gulpmatch(file, {isFile:true}); 79 | ``` 80 | ```javascript 81 | var match = gulpmatch(file, {isDirectory:false}); 82 | ``` 83 | 84 | If the condition is an object with a `isFile` or `isDirectory` property, it'll match the details on the 85 | [vinyl-fs](https://github.com/wearefractal/vinyl-fs) file's [`stat`](http://nodejs.org/api/fs.html#fs_class_fs_stats) object. 86 | 87 | #### else 88 | 89 | ```javascript 90 | var match = gulpmatch(file, 42); 91 | // match = true 92 | ``` 93 | ```javascript 94 | var match = gulpmatch(file, ''); 95 | // match = false 96 | ``` 97 | 98 | If there's no matching rule from the rules above, it'll return `true` for truthy conditions, `false` for falsey conditions (including `undefined`). 99 | 100 | ### options 101 | 102 | #### minimatch options object 103 | 104 | See for options docs. 105 | 106 | 107 | LICENSE 108 | ------- 109 | 110 | (MIT License) 111 | 112 | Copyright (c) 2014 [Richardson & Sons, LLC](http://richardsonandsons.com/) 113 | 114 | Permission is hereby granted, free of charge, to any person obtaining 115 | a copy of this software and associated documentation files (the 116 | "Software"), to deal in the Software without restriction, including 117 | without limitation the rights to use, copy, modify, merge, publish, 118 | distribute, sublicense, and/or sell copies of the Software, and to 119 | permit persons to whom the Software is furnished to do so, subject to 120 | the following conditions: 121 | 122 | The above copyright notice and this permission notice shall be 123 | included in all copies or substantial portions of the Software. 124 | 125 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 126 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 127 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 128 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 129 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 130 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 131 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 132 | --------------------------------------------------------------------------------