Permalink
Browse files

A little somethin somethin.

  • Loading branch information...
0 parents commit 5aab6ec63828dab9d60b5cc2450c38fd9dd59476 @cowboy committed Jan 11, 2012
@@ -0,0 +1 @@
+/node_modules/
@@ -0,0 +1,22 @@
+Copyright (c) 2012 "Cowboy" Ben Alman
+
+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.
@@ -0,0 +1,38 @@
+# Node Glob, Whatever
+
+A quick and dirty synchronous file globbing utility based on [minimatch](https://github.com/isaacs/minimatch).
+
+## Why another file globbing library?
+
+I wanted to make [grunt](https://github.com/cowboy/grunt) work on Windows. Unfortunately, [node-glob](https://github.com/isaacs/node-glob) doesn't work on Windows, and [miniglob](https://github.com/isaacs/miniglob) isn't synchronous.
+
+## Any issues?
+
+I'd imagine that this works with any path that [minimatch](https://github.com/isaacs/minimatch) supports. While this includes some basic unit tests, I'm hoping that minimatch has good coverage.
+
+This module isn't terribly efficient. But that's ok, because I'm using it for relatively small folder structures. Maybe someone will make this one better (patches welcome!). Or maybe even write a better one, and then I'll use that instead. But yeah, don't use this on a really large directory structure.
+
+## Getting Started
+
+This code should work just fine in Node.js:
+
+First, install the module with: `npm install glob-whatev`
+
+```javascript
+var globsync = require('glob-whatev');
+globsync.glob('foo/**/*.js') // some boolean
+
+// Basically,
+globsync.glob(globPattern [, minimatchOptions]) // some boolean
+```
+
+## Contributing
+In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [grunt](https://github.com/cowboy/grunt).
+
+## Release History
+2012/01/11 - v0.1.0 - First official release.
+
+## License
+Copyright (c) 2012 "Cowboy" Ben Alman
+Licensed under the MIT license.
+<http://benalman.com/about/license/>
@@ -0,0 +1,32 @@
+/*global config:true, task:true*/
+config.init({
+ pkg: '<json:package.json>',
+ test: {
+ files: ['test/**/*.js']
+ },
+ lint: {
+ files: ['grunt.js', 'lib/**/*.js', 'test/**/*.js']
+ },
+ watch: {
+ files: '<config:lint.files>',
+ tasks: 'lint test'
+ },
+ jshint: {
+ options: {
+ curly: true,
+ eqeqeq: true,
+ immed: true,
+ latedef: true,
+ newcap: true,
+ noarg: true,
+ sub: true,
+ undef: true,
+ eqnull: true,
+ node: true
+ },
+ globals: {}
+ }
+});
+
+// Default task.
+task.registerTask('default', 'lint test');
@@ -0,0 +1,76 @@
+var fs = require('fs');
+var path = require('path');
+
+var minimatch = require('minimatch');
+
+// Windows uses \ instead of / for path separators.
+var win32 = process.platform === 'win32';
+var pathSeparator = win32 ? '\\' : '/';
+var stripWildcard = /[*?{+(].*$/;
+var stripNonpath = win32 ? /[^\/\\]*$/ : /[^\/]*$/;
+
+// On Windows, convert all \ to /.
+function normalize(filepath) {
+ return win32 ? filepath.replace(/\\/g, '/') : filepath;
+}
+
+// A very simple, not-at-all-efficient, synchronous file globbing util.
+exports.glob = function(pattern, options) {
+ if (!options) { options = {}; }
+ // The current absolute working directory.
+ var base = normalize(path.join(process.cwd(), pathSeparator));
+ // The passed pattern, resolved to an absolute path.
+ var absPattern = normalize(path.resolve(base, pattern));
+ // Since path.resolve strips off trailing '/', add it back if necessary.
+ if (/\/$/.test(pattern)) { absPattern += '/'; }
+ // Was pattern-ass-specified already absolute?
+ var wasAbsolute = pattern === absPattern;
+ // Instead of recursing from the base looking for files, start recursing at
+ // the farthest possible subdirectory that doesn't contain any kind of
+ // wildcard characters. I may have missed one, so let me know if I have!
+ var betterBase = absPattern.replace(stripWildcard, '').replace(stripNonpath, '');
+ // Now that we've got a better base, we need a better pattern.
+ var betterPattern = absPattern.slice(betterBase.length);
+ // Don't recurse if we don't have to. Limit max depth.
+ var maxDepth = betterPattern.indexOf('**') >= 0 ? (options.maxDepth || 99)
+ : betterPattern.split('/').length;
+
+ // Iterate over all sub-files and directories in a brute-force and not-at-all
+ // efficient way.
+ var filepaths = [];
+ (function recurse(dirpath, depth) {
+ fs.readdirSync(dirpath).forEach(function(filepath) {
+ // Make relative path absolute.
+ filepath = path.join(dirpath, filepath);
+ if (fs.statSync(filepath).isDirectory()) {
+ // If the path is a directory, push it onto the array, adding a
+ // trailing /.
+ filepaths.push(filepath + pathSeparator);
+ // Recurse.
+ if (depth < maxDepth) {
+ recurse(filepath, depth + 1);
+ }
+ } else {
+ // Push file path onto the array.
+ filepaths.push(filepath);
+ }
+ });
+ }(betterBase, 1));
+
+ // Normalize filepaths and remove those that don't match pattern.
+ filepaths = filepaths.map(normalize).filter(function(filepath) {
+ return minimatch(filepath, absPattern, options);
+ });
+
+ // If the pattern wasn't absolute, replace each absolute filepath with one
+ // that is relative to the cwd.
+ if (!wasAbsolute) {
+ filepaths = filepaths.map(function(filepath) {
+ var relPath = normalize(path.relative(process.cwd(), filepath));
+ if (/\/$/.test(filepath)) { relPath += '/'; }
+ return relPath;
+ });
+ }
+
+ return filepaths;
+};
@@ -0,0 +1,30 @@
+{
+ "author": "\"Cowboy\" Ben Alman (http://benalman.com/)",
+ "name": "glob-whatev",
+ "description": "A quick and dirty file globbing utility based on minimatch.",
+ "version": "0.1.0",
+ "homepage": "http://github.com/cowboy/node-glob-whatev",
+ "bugs": "https://github.com/cowboy/node-glob-whatev/issues",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/cowboy/node-glob-whatev.git"
+ },
+ "licenses": {
+ "type": "MIT",
+ "url": "http://github.com/cowboy/node-glob-whatev/LICENSE-MIT"
+ },
+ "main": "lib/glob",
+ "engines": {
+ "node": "~0.6.6"
+ },
+ "keywords": [
+ "glob",
+ "wildcard",
+ "star",
+ "file"
+ ],
+ "dependencies": {
+ "minimatch": "~0.1.3"
+ },
+ "devDependencies": {}
+}
No changes.
No changes.
No changes.
No changes.
@@ -0,0 +1,76 @@
+var path = require('path');
+var globsync = require('../lib/glob');
+
+// On Windows, convert all \ to /.
+function normalize(filepath) {
+ return process.platform === 'win32' ? filepath.replace(/\\/g, '/') : filepath;
+}
+
+function makeAbsolute(filepath) {
+ var abspath = normalize(path.resolve(process.cwd(), filepath));
+ if (/\/$/.test(filepath)) { abspath += '/'; }
+ return abspath;
+}
+
+var allFiles = [
+ 'test/fixture/boot',
+ 'test/fixture/foo/',
+ 'test/fixture/foo/bar/',
+ 'test/fixture/foo/bar/baz/',
+ 'test/fixture/foo/bar/baz/boot',
+ 'test/fixture/foo/bar/boot',
+ 'test/fixture/foo/boot'
+];
+
+function fileList(arr, prefix) {
+ return arr.map(function(i) {
+ var filepath = allFiles[i];
+ return prefix ? normalize(path.join(prefix, filepath)) : filepath;
+ });
+}
+
+exports['globsync'] = {
+ 'relative': function(test) {
+ test.expect(9);
+ test.deepEqual(globsync.glob('test/fixture/*'), fileList([0,1]), 'test/fixture/* should match');
+ test.deepEqual(globsync.glob('test/fixture/*/*'), fileList([2,6]), 'test/fixture/* should match');
+ test.deepEqual(globsync.glob('test/fixture/**'), fileList([0,1,2,3,4,5,6]), 'test/fixture/** should match');
+ test.deepEqual(globsync.glob('test/fixture/**/'), fileList([1,2,3]), 'test/fixture/**/ should match');
+ test.deepEqual(globsync.glob('test/fixture/**/b*'), fileList([0,2,3,4,5,6]), 'test/fixture/**/b* should match');
+ test.deepEqual(globsync.glob('test/fixture/**/b*/'), fileList([2,3]), 'test/fixture/**/b*/ should match');
+ test.deepEqual(globsync.glob('test/fixture/**/b??'), fileList([2,3]), 'test/fixture/**/b?? should match');
+ test.deepEqual(globsync.glob('test/fixture/**/b???'), fileList([0,4,5,6]), 'test/fixture/**/b??? should match');
+ test.deepEqual(globsync.glob('test/fixture/**/?oo'), fileList([1]), 'test/fixture/**/?oo should match');
+ test.done();
+ },
+ 'absolute': function(test) {
+ test.expect(9);
+ var prefix = path.resolve(process.cwd());
+ test.deepEqual(globsync.glob(makeAbsolute('test/fixture/*')), fileList([0,1], prefix), makeAbsolute('test/fixture/*') + ' should match');
+ test.deepEqual(globsync.glob(makeAbsolute('test/fixture/*/*')), fileList([2,6], prefix), makeAbsolute('test/fixture/*/*') + ' should match');
+ test.deepEqual(globsync.glob(makeAbsolute('test/fixture/**')), fileList([0,1,2,3,4,5,6], prefix), makeAbsolute('test/fixture/**') + ' should match');
+ test.deepEqual(globsync.glob(makeAbsolute('test/fixture/**/')), fileList([1,2,3], prefix), makeAbsolute('test/fixture/**/') + ' should match');
+ test.deepEqual(globsync.glob(makeAbsolute('test/fixture/**/b*')), fileList([0,2,3,4,5,6], prefix), makeAbsolute('test/fixture/**/b*') + ' should match');
+ test.deepEqual(globsync.glob(makeAbsolute('test/fixture/**/b*/')), fileList([2,3], prefix), makeAbsolute('test/fixture/**/b*/') + ' should match');
+ test.deepEqual(globsync.glob(makeAbsolute('test/fixture/**/b??')), fileList([2,3], prefix), makeAbsolute('test/fixture/**/b??') + ' should match');
+ test.deepEqual(globsync.glob(makeAbsolute('test/fixture/**/b???')), fileList([0,4,5,6], prefix), makeAbsolute('test/fixture/**/b???') + ' should match');
+ test.deepEqual(globsync.glob(makeAbsolute('test/fixture/**/?oo')), fileList([1], prefix), makeAbsolute('test/fixture/**/?oo') + ' should match');
+ test.done();
+ },
+ 'wacky': function(test) {
+ test.expect(9);
+ process.chdir('lib');
+ var prefix = '../';
+ test.deepEqual(globsync.glob('../test/fixture/*'), fileList([0,1], prefix), '../test/fixture/* should match');
+ test.deepEqual(globsync.glob('../test/fixture/*/*'), fileList([2,6], prefix), '../test/fixture/*/* should match');
+ test.deepEqual(globsync.glob('../test/fixture/**'), fileList([0,1,2,3,4,5,6], prefix), '../test/fixture/** should match');
+ test.deepEqual(globsync.glob('../test/fixture/**/'), fileList([1,2,3], prefix), '../test/fixture/**/ should match');
+ test.deepEqual(globsync.glob('../test/fixture/**/b*'), fileList([0,2,3,4,5,6], prefix), '../test/fixture/**/b* should match');
+ test.deepEqual(globsync.glob('../test/fixture/**/b*/'), fileList([2,3], prefix), '../test/fixture/**/b*/ should match');
+ test.deepEqual(globsync.glob('../test/fixture/**/b??'), fileList([2,3], prefix), '../test/fixture/**/b?? should match');
+ test.deepEqual(globsync.glob('../test/fixture/**/b???'), fileList([0,4,5,6], prefix), '../test/fixture/**/b??? should match');
+ test.deepEqual(globsync.glob('../test/fixture/**/?oo'), fileList([1], prefix), '../test/fixture/**/?oo should match');
+ process.chdir('..');
+ test.done();
+ }
+};

0 comments on commit 5aab6ec

Please sign in to comment.