├── test ├── fixture │ ├── boot │ └── foo │ │ ├── boot │ │ └── bar │ │ ├── boot │ │ └── baz │ │ └── boot └── glob_test.js ├── .gitignore ├── README.md ├── grunt.js ├── package.json ├── LICENSE-MIT └── lib └── glob.js /test/fixture/boot: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixture/foo/boot: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixture/foo/bar/boot: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | -------------------------------------------------------------------------------- /test/fixture/foo/bar/baz/boot: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## THIS PROJECT IS DEPRECATED 2 | 3 | Now that [node-glob](https://github.com/isaacs/node-glob) works cross-OS and supports synchronous globbing, this project will no longer be supported. Use that instead. 4 | -------------------------------------------------------------------------------- /grunt.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | // Project configuration. 4 | grunt.initConfig({ 5 | pkg: '', 6 | test: { 7 | files: ['test/**/*.js'] 8 | }, 9 | lint: { 10 | files: ['grunt.js', 'lib/**/*.js', 'test/**/*.js'] 11 | }, 12 | watch: { 13 | files: '', 14 | tasks: 'default' 15 | }, 16 | jshint: { 17 | options: { 18 | curly: true, 19 | eqeqeq: true, 20 | immed: true, 21 | latedef: true, 22 | newcap: true, 23 | noarg: true, 24 | sub: true, 25 | undef: true, 26 | boss: true, 27 | eqnull: true, 28 | node: true 29 | }, 30 | globals: { 31 | exports: true 32 | } 33 | } 34 | }); 35 | 36 | // Default task. 37 | grunt.registerTask('default', 'lint test'); 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "glob-whatev", 3 | "description": "A quick and dirty file globbing utility based on minimatch.", 4 | "version": "0.1.8", 5 | "homepage": "http://github.com/cowboy/node-glob-whatev", 6 | "author": { 7 | "name": "\"Cowboy\" Ben Alman", 8 | "url": "http://benalman.com/" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git://github.com/cowboy/node-glob-whatev.git" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/cowboy/node-glob-whatev/issues" 16 | }, 17 | "licenses": [ 18 | { 19 | "type": "MIT", 20 | "url": "http://github.com/cowboy/node-glob-whatev/blob/master/LICENSE-MIT" 21 | } 22 | ], 23 | "dependencies": { 24 | "minimatch": "~0.2.5" 25 | }, 26 | "devDependencies": { 27 | "grunt": "~0.3.11" 28 | }, 29 | "keywords": [ 30 | "glob", 31 | "wildcard", 32 | "star", 33 | "file", 34 | "sync", 35 | "synchronous" 36 | ], 37 | "engines": { 38 | "node": ">= 0.6.0" 39 | }, 40 | "main": "lib/glob", 41 | "scripts": { 42 | "test": "grunt test" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 "Cowboy" Ben Alman 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /lib/glob.js: -------------------------------------------------------------------------------- 1 | /* 2 | * glob-whatev 3 | * http://github.com/cowboy/node-glob-whatev 4 | * 5 | * Copyright (c) 2012 "Cowboy" Ben Alman 6 | * Licensed under the MIT license. 7 | * http://benalman.com/about/license/ 8 | */ 9 | 10 | var fs = require('fs'); 11 | var path = require('path'); 12 | var existsSync = fs.existsSync || path.existsSync; 13 | 14 | // Export minimatch, in case something else needs direct access to it. 15 | exports.minimatch = require('minimatch'); 16 | 17 | // Windows uses \ instead of / for path separators. 18 | var win32 = process.platform === 'win32'; 19 | var pathSeparator = win32 ? '\\' : '/'; 20 | var stripWildcard = /[*?{+(].*$/; 21 | var stripNonpath = win32 ? /[^\/\\]*$/ : /[^\/]*$/; 22 | 23 | // On Windows, convert all \ to /. 24 | function normalize(filepath) { 25 | return win32 ? filepath.replace(/\\/g, '/') : filepath; 26 | } 27 | 28 | // A very simple, not-at-all-efficient, synchronous file globbing util. 29 | exports.glob = function(pattern, options) { 30 | if (!options) { options = {}; } 31 | var cwd = options.cwd || process.cwd(); 32 | // The current absolute working directory. 33 | var base = normalize(path.join(cwd, pathSeparator)); 34 | // The passed pattern, resolved to an absolute path. 35 | var absPattern = normalize(path.resolve(base, pattern)); 36 | // Since path.resolve strips off trailing '/', add it back if necessary. 37 | if (/\/$/.test(pattern) && !/\/$/.test(absPattern)) { absPattern += '/'; } 38 | // Was pattern-as-specified already absolute? 39 | var wasAbsolute = normalize(pattern) === absPattern; 40 | // Instead of recursing from the base looking for files, start recursing at 41 | // the farthest possible subdirectory that doesn't contain any kind of 42 | // wildcard characters. I may have missed one, so let me know if I have! 43 | var betterBase = absPattern.replace(stripWildcard, '').replace(stripNonpath, ''); 44 | // Now that we've got a better base, we need a better pattern. 45 | var betterPattern = absPattern.slice(betterBase.length); 46 | // Don't recurse if we don't have to. Limit max depth. 47 | var maxDepth = betterPattern.indexOf('**') >= 0 ? (options.maxDepth || 99) 48 | : betterPattern.split('/').length; 49 | // If minimatch 'matchBase' option is true, and the pattern doesn't contain 50 | // ** or /, use the pattern as-specified and recurse to max. 51 | if (options.matchBase && !/\*\*|\//.test(pattern)) { 52 | maxDepth = options.maxDepth || 99; 53 | absPattern = pattern; 54 | } 55 | // Build file list, recursively (only up to a certain depth). 56 | var recurse = function(dirpath, depth) { 57 | // Abort if, for whatever reason, dirpath doesn't exist. 58 | if (!existsSync(dirpath)) { return; } 59 | // Read directory contents. 60 | fs.readdirSync(dirpath).forEach(function(filepath) { 61 | var stat; 62 | // Make relative path absolute. 63 | filepath = path.join(dirpath, filepath); 64 | try { 65 | stat = fs.statSync(filepath); 66 | } catch (e) { 67 | // Ignore files that can't be "stat"ed (such as emacs's lock files) 68 | } 69 | if (stat && stat.isDirectory()) { 70 | // If the path is a directory, push it onto the array, adding a 71 | // trailing /. 72 | filepaths.push(filepath + pathSeparator); 73 | // Recurse. 74 | if (depth < maxDepth) { 75 | recurse(filepath, depth + 1); 76 | } 77 | } else { 78 | // Push file path onto the array. 79 | filepaths.push(filepath); 80 | } 81 | }); 82 | }; 83 | // Build files list. 84 | var filepaths = []; 85 | if (betterPattern) { 86 | // A pattern exists, recurse starting at betterBase. 87 | recurse(betterBase, 1); 88 | } else { 89 | // No pattern exists, just use betterBase path. 90 | filepaths.push(betterBase); 91 | } 92 | // Normalize filepaths and remove those that don't match pattern. 93 | filepaths = filepaths.map(normalize).filter(function(filepath) { 94 | return exports.minimatch(filepath, absPattern, options); 95 | }); 96 | 97 | // If the pattern wasn't absolute, replace each absolute filepath with one 98 | // that is relative to the cwd. 99 | if (!wasAbsolute) { 100 | filepaths = filepaths.map(function(filepath) { 101 | var relPath = normalize(path.relative(cwd, filepath)); 102 | if (/\/$/.test(filepath)) { relPath += '/'; } 103 | return relPath; 104 | }); 105 | } 106 | 107 | return filepaths; 108 | }; 109 | -------------------------------------------------------------------------------- /test/glob_test.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var globsync = require('../lib/glob'); 3 | 4 | // Run tests from within "test" directory. 5 | process.chdir('test'); 6 | 7 | // On Windows, convert all \ to /. 8 | function normalize(filepath) { 9 | return process.platform === 'win32' ? filepath.replace(/\\/g, '/') : filepath; 10 | } 11 | 12 | function makeAbsolute(filepath) { 13 | var abspath = path.resolve(process.cwd(), filepath); 14 | if (/\/$/.test(filepath)) { abspath += '/'; } 15 | return abspath; 16 | } 17 | 18 | var allFiles = [ 19 | 'fixture/boot', 20 | 'fixture/foo/', 21 | 'fixture/foo/bar/', 22 | 'fixture/foo/bar/baz/', 23 | 'fixture/foo/bar/baz/boot', 24 | 'fixture/foo/bar/boot', 25 | 'fixture/foo/boot' 26 | ]; 27 | 28 | function fileList(arr, prefix) { 29 | return arr.map(function(i) { 30 | var filepath = allFiles[i]; 31 | return prefix ? normalize(path.join(prefix, filepath)) : filepath; 32 | }); 33 | } 34 | 35 | function relFileList(arr) { 36 | return fileList(arr).map(function(filepath) { 37 | // Strip leading fixture/ from each path 38 | return filepath.replace(/^fixture\//, ''); 39 | }); 40 | } 41 | 42 | exports['globsync'] = { 43 | 'relative': function(test) { 44 | test.expect(13); 45 | test.deepEqual(globsync.glob('fixture/*'), fileList([0,1]), 'test/fixture/* should match'); 46 | test.deepEqual(globsync.glob('fixture/foo'), fileList([1]), 'test/fixture/foo should match'); 47 | test.deepEqual(globsync.glob('fixture/foo/'), fileList([1]), 'test/fixture/foo/ should match'); 48 | test.deepEqual(globsync.glob('fixture/*/*'), fileList([2,6]), 'test/fixture/* should match'); 49 | test.deepEqual(globsync.glob('fixture/**'), fileList([0,1,2,3,4,5,6]), 'test/fixture/** should match'); 50 | test.deepEqual(globsync.glob('fixture/**/'), fileList([1,2,3]), 'test/fixture/**/ should match'); 51 | test.deepEqual(globsync.glob('fixture/**/b*'), fileList([0,2,3,4,5,6]), 'test/fixture/**/b* should match'); 52 | test.deepEqual(globsync.glob('fixture/**/b*/'), fileList([2,3]), 'test/fixture/**/b*/ should match'); 53 | test.deepEqual(globsync.glob('fixture/**/b??'), fileList([2,3]), 'test/fixture/**/b?? should match'); 54 | test.deepEqual(globsync.glob('fixture/**/b???'), fileList([0,4,5,6]), 'test/fixture/**/b??? should match'); 55 | test.deepEqual(globsync.glob('fixture/**/?oo'), fileList([1]), 'test/fixture/**/?oo should match'); 56 | test.deepEqual(globsync.glob('fixture/fail'), [], 'test/fixture/fail should match nothing (and not fail)'); 57 | test.deepEqual(globsync.glob('fixture/fail/*'), [], 'test/fixture/fail/* should match nothing (and not fail)'); 58 | test.done(); 59 | }, 60 | 'absolute': function(test) { 61 | test.expect(11); 62 | var prefix = path.resolve(process.cwd()); 63 | test.deepEqual(globsync.glob(makeAbsolute('fixture/*')), fileList([0,1], prefix), makeAbsolute('test/fixture/*') + ' should match'); 64 | test.deepEqual(globsync.glob(makeAbsolute('fixture/foo')), fileList([1], prefix), makeAbsolute('test/fixture/foo') + ' should match'); 65 | test.deepEqual(globsync.glob(makeAbsolute('fixture/foo/')), fileList([1], prefix), makeAbsolute('test/fixture/foo/') + ' should match'); 66 | test.deepEqual(globsync.glob(makeAbsolute('fixture/*/*')), fileList([2,6], prefix), makeAbsolute('test/fixture/*/*') + ' should match'); 67 | test.deepEqual(globsync.glob(makeAbsolute('fixture/**')), fileList([0,1,2,3,4,5,6], prefix), makeAbsolute('test/fixture/**') + ' should match'); 68 | test.deepEqual(globsync.glob(makeAbsolute('fixture/**/')), fileList([1,2,3], prefix), makeAbsolute('test/fixture/**/') + ' should match'); 69 | test.deepEqual(globsync.glob(makeAbsolute('fixture/**/b*')), fileList([0,2,3,4,5,6], prefix), makeAbsolute('test/fixture/**/b*') + ' should match'); 70 | test.deepEqual(globsync.glob(makeAbsolute('fixture/**/b*/')), fileList([2,3], prefix), makeAbsolute('test/fixture/**/b*/') + ' should match'); 71 | test.deepEqual(globsync.glob(makeAbsolute('fixture/**/b??')), fileList([2,3], prefix), makeAbsolute('test/fixture/**/b??') + ' should match'); 72 | test.deepEqual(globsync.glob(makeAbsolute('fixture/**/b???')), fileList([0,4,5,6], prefix), makeAbsolute('test/fixture/**/b???') + ' should match'); 73 | test.deepEqual(globsync.glob(makeAbsolute('fixture/**/?oo')), fileList([1], prefix), makeAbsolute('test/fixture/**/?oo') + ' should match'); 74 | test.done(); 75 | }, 76 | 'wacky': function(test) { 77 | test.expect(11); 78 | process.chdir('../lib'); 79 | var prefix = '../test/'; 80 | test.deepEqual(globsync.glob('../test/fixture/*'), fileList([0,1], prefix), '../test/fixture/* should match'); 81 | test.deepEqual(globsync.glob('../test/fixture/foo'), fileList([1], prefix), '../test/fixture/foo should match'); 82 | test.deepEqual(globsync.glob('../test/fixture/foo/'), fileList([1], prefix), '../test/fixture/foo/ should match'); 83 | test.deepEqual(globsync.glob('../test/fixture/*/*'), fileList([2,6], prefix), '../test/fixture/*/* should match'); 84 | test.deepEqual(globsync.glob('../test/fixture/**'), fileList([0,1,2,3,4,5,6], prefix), '../test/fixture/** should match'); 85 | test.deepEqual(globsync.glob('../test/fixture/**/'), fileList([1,2,3], prefix), '../test/fixture/**/ should match'); 86 | test.deepEqual(globsync.glob('../test/fixture/**/b*'), fileList([0,2,3,4,5,6], prefix), '../test/fixture/**/b* should match'); 87 | test.deepEqual(globsync.glob('../test/fixture/**/b*/'), fileList([2,3], prefix), '../test/fixture/**/b*/ should match'); 88 | test.deepEqual(globsync.glob('../test/fixture/**/b??'), fileList([2,3], prefix), '../test/fixture/**/b?? should match'); 89 | test.deepEqual(globsync.glob('../test/fixture/**/b???'), fileList([0,4,5,6], prefix), '../test/fixture/**/b??? should match'); 90 | test.deepEqual(globsync.glob('../test/fixture/**/?oo'), fileList([1], prefix), '../test/fixture/**/?oo should match'); 91 | process.chdir('../test'); 92 | test.done(); 93 | }, 94 | 'options.matchBase': function(test) { 95 | test.expect(3); 96 | test.deepEqual(globsync.glob('boot', {matchBase: true}), fileList([0, 4, 5, 6], ''), 'should match.'); 97 | test.deepEqual(globsync.glob('**/boot', {matchBase: true}), fileList([0, 4, 5, 6], ''), 'should match.'); 98 | test.deepEqual(globsync.glob('**/b*/boot', {matchBase: true}), fileList([4, 5], ''), 'should match.'); 99 | test.done(); 100 | }, 101 | 'options.cwd': function(test) { 102 | test.expect(4); 103 | test.deepEqual(globsync.glob('**', {cwd: 'fixture'}), relFileList([0,1,2,3,4,5,6]), '** should match'); 104 | test.deepEqual(globsync.glob('**', {cwd: 'fixture/'}), relFileList([0,1,2,3,4,5,6]), '** should match'); 105 | test.deepEqual(globsync.glob('*', {cwd: 'fixture'}), relFileList([0,1]), '* should match'); 106 | test.deepEqual(globsync.glob('*/', {cwd: 'fixture'}), relFileList([1]), '* should match'); 107 | test.done(); 108 | }, 109 | 'options.maxDepth': function(test) { 110 | test.expect(4); 111 | test.deepEqual(globsync.glob('fixture/**', {maxDepth: 1}), fileList([0,1]), 'maxDepth should limit search'); 112 | test.deepEqual(globsync.glob('fixture/**', {maxDepth: 2}), fileList([0,1,2,6]), 'maxDepth should limit search'); 113 | test.deepEqual(globsync.glob('**', {cwd: 'fixture', maxDepth: 1}), relFileList([0,1]), 'maxDepth should limit search'); 114 | test.deepEqual(globsync.glob('**', {cwd: 'fixture', maxDepth: 2}), relFileList([0,1,2,6]), 'maxDepth should limit search'); 115 | test.done(); 116 | } 117 | }; 118 | --------------------------------------------------------------------------------