173 lines
4 KiB
JavaScript
173 lines
4 KiB
JavaScript
var fs = require( 'fs' )
|
|
var path = require( 'path' )
|
|
var minimatch = require( 'minimatch' )
|
|
|
|
function log () {
|
|
// console.log.apply( this, arguments )
|
|
}
|
|
|
|
function glob ( pattern, opts, callback ) {
|
|
var filesFound = {}
|
|
var dirsFound = {}
|
|
opts = opts || {}
|
|
|
|
var errors = []
|
|
var _dirsOnly = ( pattern[ pattern.length - 1 ] === path.sep )
|
|
|
|
var dirPattern = pattern.slice( 0, pattern.lastIndexOf( path.sep ) )
|
|
if ( dirPattern[ dirPattern.length - 1 ] !== path.sep ) dirPattern += path.sep
|
|
|
|
log( 'dirPattern: ' + dirPattern )
|
|
log( 'dirsOnly: ' + _dirsOnly )
|
|
|
|
if ( typeof opts === 'function' ) {
|
|
callback = opts
|
|
opts = {}
|
|
}
|
|
|
|
var globstar = false
|
|
|
|
if ( pattern.indexOf( '**' ) >= 0 ) globstar = true
|
|
|
|
var ignoreList = ( opts.ignore || opts.ignored || [] )
|
|
|
|
if ( !( ignoreList instanceof Array ) ) ignoreList = [ ignoreList ]
|
|
|
|
if ( !opts.ignoreDefaults ) {
|
|
// ignore node_modules
|
|
ignoreList.push( '**/node_modules/**' )
|
|
ignoreList.push( 'node_modules' )
|
|
|
|
// ignore dotfiles
|
|
ignoreList.push( '**/.*' )
|
|
ignoreList.push( '.git' )
|
|
}
|
|
|
|
var MAX_DEPTH = ( opts.depth || 7 )
|
|
|
|
var firstStarIndex = pattern.indexOf( '*' )
|
|
|
|
var root = ( pattern.slice( 0, firstStarIndex ) || '.' )
|
|
|
|
log( 'root: ' + root )
|
|
|
|
// yolo into the disk
|
|
yolo( root, 1, MAX_DEPTH )
|
|
|
|
var callbacks = 1
|
|
var callbacksFinished = 0
|
|
|
|
var _timeout
|
|
function finishCallback () {
|
|
callbacksFinished++
|
|
|
|
clearTimeout( _timeout )
|
|
_timeout = setTimeout( function () {
|
|
log( callbacks + ' / ' + callbacksFinished )
|
|
if ( callbacks === callbacksFinished ) {
|
|
// we're done!
|
|
var files = Object.keys( filesFound )
|
|
var dirs = Object.keys( dirsFound )
|
|
|
|
var err = null
|
|
if ( errors.length > 0 ) {
|
|
err = errors
|
|
errors.forEach( function ( e ) {
|
|
log( e )
|
|
} )
|
|
}
|
|
|
|
log( 'finished! files found: ' + files.length )
|
|
callback( err, files, dirs )
|
|
}
|
|
}, 1 )
|
|
}
|
|
|
|
function add () {
|
|
callbacks++
|
|
}
|
|
|
|
function yolo ( dirpath, depth, MAX_DEPTH ) {
|
|
if ( !MAX_DEPTH ) MAX_DEPTH = 6
|
|
|
|
log( 'yoloing ' + depth + ' / ' + MAX_DEPTH )
|
|
|
|
add()
|
|
fs.readdir( dirpath, function ( err, files ) {
|
|
finishCallback()
|
|
|
|
if ( err ) {
|
|
return errors.push( err )
|
|
}
|
|
|
|
files.forEach( function ( file ) {
|
|
log( 'path: ' + file )
|
|
var filepath = path.join( dirpath, file )
|
|
file = filepath
|
|
|
|
add()
|
|
fs.stat( file, function ( err, stats ) {
|
|
finishCallback()
|
|
|
|
if ( err ) {
|
|
return errors.push( { path: file, err: err } )
|
|
}
|
|
|
|
for ( var i = 0; i < ignoreList.length; i++ ) {
|
|
var ignorePattern = ignoreList[ i ]
|
|
var shouldIgnore = minimatch( file, ignorePattern )
|
|
if ( shouldIgnore ) return
|
|
}
|
|
|
|
if ( stats.isDirectory() ) {
|
|
log( 'dir: ' + file )
|
|
|
|
var dir = file
|
|
if ( dir[ dir.length - 1 ] !== path.sep ) dir += path.sep
|
|
|
|
var matches = minimatch( dir, dirPattern )
|
|
|
|
if ( matches ) {
|
|
dirsFound[ file ] = file
|
|
log( 'found dir match: ' + file )
|
|
|
|
if ( _dirsOnly ) {
|
|
filesFound[ file ] = file
|
|
}
|
|
}
|
|
|
|
// TODO yolo level deeper
|
|
if ( globstar ) {
|
|
if ( depth < MAX_DEPTH ) {
|
|
yolo( file, depth + 1 )
|
|
} else {
|
|
log( 'MAX_DEPTH reached: ' + depth + ' / ' + MAX_DEPTH )
|
|
}
|
|
}
|
|
} else if ( stats.isFile() ) {
|
|
if ( _dirsOnly ) return
|
|
|
|
log( 'file: ' + file )
|
|
|
|
var matches = minimatch( file, pattern )
|
|
|
|
if ( matches ) {
|
|
filesFound[ file ] = file
|
|
log( 'found match: ' + file )
|
|
}
|
|
}
|
|
} )
|
|
} )
|
|
} )
|
|
}
|
|
}
|
|
|
|
glob.hasMagic = function ( pattern ) {
|
|
return ( pattern.indexOf( '*' ) >= 0 )
|
|
}
|
|
|
|
module.exports = glob
|
|
|
|
// glob( 'test/tmp/**.css', function ( files ) {
|
|
// console.log( files )
|
|
// } )
|