Skip to content

Commit

Permalink
add depthLimit option, update benchmark & readme
Browse files Browse the repository at this point in the history
  • Loading branch information
manidlou committed Apr 29, 2018
1 parent ac99fb4 commit 04a9491
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 139 deletions.
50 changes: 15 additions & 35 deletions README.md
Expand Up @@ -22,13 +22,15 @@ Usage
- `directory` `<String>`
- `options` `<Object>` (optional) _all options are `false` by default_
- `nodir` `<Boolean>`
- return only files (ignore directories)
- return only files (ignore directories).
- `nofile` `<Boolean>`
- return only directories (ignore files)
- `noRecurseOnFailedFilter` `<Boolean>`
- when `filter` function is used, the default behavior is to read all directories even if they don't pass the `filter` function (won't be included but still will be traversed). If you set `true`, there will be neither inclusion nor traversal for directories that don't pass the `filter` function
- return only directories (ignore files).
- `depthLimit`: `<Number>`
- the number of times to recurse before stopping. -1 for unlimited.
- `fs`: `<Object>`
- custom `fs`, useful for mocking `fs` object.
- `filter` `<Function>`
- function that gets one argument `fn({path: '', stats: {}})` and returns true to include or false to exclude the item
- function that gets one argument `fn({path: '', stats: {}})` and returns true to include or false to exclude the item.

- **Return:** `<Array<Object>>` `[{path: '', stats: {}}]`

Expand Down Expand Up @@ -74,39 +76,19 @@ const dirs = klawSync('/some/dir', {nofile: true})
// dirs = [{path: '/some/dir/dir1', stats: {}}, {path: '/some/dir/dir2', stats: {}}]
```

_**ignore `node_modules`**_
_**ignore hidden directories**_

Notice here `noRecurseOnFailedFilter: true` option is used since we don't want anything from `node_modules` (no inclusion and no traversal).

```js
const klawSync = require('klaw-sync')

const filterFn = item => item.path.indexOf('node_modules') < 0

const paths = klawSync('/some/dir', { filter: filterFn, noRecurseOnFailedFilter: true })
```

_**ignore `node_modules` and `.git`**_

```js
const klawSync = require('klaw-sync')

const filterFn = item => item.path.indexOf('node_modules') < 0 && item.path.indexOf('.git') < 0

const paths = klawSync('/some/dir', { filter: filterFn, noRecurseOnFailedFilter: true })
```

_**get all `js` files**_

Here `noRecurseOnFailedFilter` option is not required since we are interested in all `js` files. In other words, although no directories pass the `filter` function, we still want to read them and see if they have any `js` files.

```js
const path = require('path')
const klawSync = require('klaw-sync')

const filterFn = item => path.extname(item.path) === '.js'
const filterFn = item => {
const basename = path.basename(item.path)
return basename === '.' || basename[0] !== '.'
}

const paths = klawSync('/some/dir', { filter: filterFn })
const paths = klawSync('/some/dir', { filter: filterFn})
```

_**filter based on stats**_
Expand Down Expand Up @@ -135,7 +117,7 @@ lint & unit: `npm test`
Performance compare to other similar modules
-----------------------------------------------

The `bm.js` runs some basic [benchmark](https://github.com/bestiejs/benchmark.js) tests for two cases: basic usage and with `--nodir=true` (get files only), on these modules:
Running some basic [benchmark](https://github.com/bestiejs/benchmark.js) tests on these modules:

- `klaw-sync`
- [walk-sync](https://github.com/joliss/node-walk-sync)
Expand All @@ -145,9 +127,7 @@ It turned out (as of January 25, 2017) for the most cases `klaw-sync` is faster

##### run benchmark

`npm run benchmark -- --dir=/some/dir`

`npm run benchmark -- --dir=/some/dir --nodir=true`
`npm run benchmark`

Credit
------
Expand Down
14 changes: 2 additions & 12 deletions benchmark/bm.js
Expand Up @@ -2,7 +2,6 @@
const fs = require('fs-extra')
const path = require('path')
const mkp = require('mkp')
const argv = require('minimist')(process.argv.slice(2))
const Benchmark = require('benchmark')
const walkSync = require('walk-sync')
const globSync = require('glob').sync
Expand Down Expand Up @@ -74,16 +73,7 @@ function run (root, opts) {
console.log('Running benchmark tests..')
paths.forEach(p => {
setup(p)
const items = klawSync(testDir)
if (argv.nodir) {
const filesLen = items.filter(item => !item.stats.isDirectory()).length
console.log('\noption.nodir: true')
console.log(`root dir length: ${items.length}`)
console.log(`files: ${filesLen}\n`)
run(testDir, {nodir: true})
} else {
console.log(`\nroot dir length: ${items.length}\n`)
run(testDir)
}
console.log(`\nroot dir length: ${klawSync(testDir).length}`)
run(testDir)
tearDown()
})
6 changes: 2 additions & 4 deletions klaw-sync.js
Expand Up @@ -18,16 +18,14 @@ function klawSync (dir, opts, ls) {
if (!st.isDirectory() || (opts.rootDepth && pi.split(path.sep).length - opts.rootDepth >= opts.depthLimit)) {
if (opts.filter) {
if (opts.filter(item) && !opts.nofile) ls.push(item)
} else {
if (!opts.nofile) ls.push(item)
} else if (!opts.nofile) {
ls.push(item)
}
} else {
if (opts.filter) {
if (opts.filter(item) && !opts.nodir) {
ls.push(item)
ls = klawSync(pi, opts, ls)
} else {
if (!opts.noRecurseOnFailedFilter) ls = klawSync(pi, opts, ls)
}
} else {
if (!opts.nodir) ls.push(item)
Expand Down
7 changes: 3 additions & 4 deletions package.json
Expand Up @@ -26,13 +26,12 @@
},
"devDependencies": {
"benchmark": "^2.1.4",
"fs-extra": "^1.0.0",
"fs-extra": "^5.0.0",
"glob": "^7.1.2",
"memory-fs": "^0.4.1",
"minimist": "^1.2.0",
"mkp": "^1.0.1",
"mocha": "^3.5.0",
"standard": "^8.6.0",
"mocha": "^5.1.1",
"standard": "^11.0.1",
"walk-sync": "^0.3.2"
},
"standard": {
Expand Down
11 changes: 4 additions & 7 deletions test/klaw-sync-customfs.test.js
Expand Up @@ -73,15 +73,12 @@ describe('klaw-sync / custom fs', () => {

describe('when opts.filter is true', () => {
it('should filter based on path', () => {
const f1 = path.join(TEST_DIR, 'dir1', 'foo.js')
const f2 = path.join(TEST_DIR, 'dir2', 'dir2_1', 'bar.js')
const f1 = path.join(TEST_DIR, 'foo.js')
const f2 = path.join(TEST_DIR, 'bar.js')
cfs.writeFileSync(f1, 'f1 file')
cfs.writeFileSync(f2, 'f2 file')
const paths = [
{path: f1, stats: cfs.statSync(f1)},
{path: f2, stats: cfs.statSync(f2)}
]
const filterFunc = i => path.extname(i.path) === '.js'
const paths = [{path: f1, stats: cfs.statSync(f1)}]
const filterFunc = i => path.basename(i.path).indexOf('foo') > -1
const items = klawSync(TEST_DIR, {filter: filterFunc, fs: cfs})
assert.strictEqual(items.length, paths.length)
items.forEach((p, i) => {
Expand Down
104 changes: 27 additions & 77 deletions test/klaw-sync.test.js
Expand Up @@ -90,15 +90,12 @@ describe('klaw-sync', () => {

describe('when opts.filter is true', () => {
it('should filter based on path', () => {
const f1 = path.join(TEST_DIR, 'dir1', 'foo.js')
const f2 = path.join(TEST_DIR, 'dir2', 'dir2_1', 'bar.js')
const f1 = path.join(TEST_DIR, 'foo.js')
const f2 = path.join(TEST_DIR, 'bar.js')
fs.ensureFileSync(f1)
fs.ensureFileSync(f2)
const paths = [
{path: f1, stats: fs.statSync(f1)},
{path: f2, stats: fs.statSync(f2)}
]
const filterFunc = i => path.extname(i.path) === '.js'
const paths = [{path: f1, stats: fs.statSync(f1)}]
const filterFunc = i => path.basename(i.path).indexOf('foo') > -1
const items = klawSync(TEST_DIR, {filter: filterFunc})
assert.strictEqual(items.length, paths.length)
items.forEach((p, i) => {
Expand All @@ -109,16 +106,17 @@ describe('klaw-sync', () => {
})

it('should filter based on stats', () => {
const f1 = path.join(TEST_DIR, 'dir1', 'foo.js')
const f2 = path.join(TEST_DIR, 'dir2', 'dir2_1', 'bar.js')
const f1 = path.join(TEST_DIR, 'bar.js')
const f2 = path.join(TEST_DIR, 'foo.js')
fs.outputFileSync(f1, 'test file 1 contents')
fs.outputFileSync(f2, 'test file 2 contents')
const paths = [
{path: f1, stats: fs.statSync(f1)},
{path: f2, stats: fs.statSync(f2)}
]
const filterFunc = i => i.stats.isFile() && i.stats.size > 0
const filterFunc = i => i.path === TEST_DIR || (i.stats.isFile() && i.stats.size > 0)
const items = klawSync(TEST_DIR, {filter: filterFunc})
items.sort()
assert.strictEqual(items.length, paths.length)
items.forEach((p, i) => {
assert.deepStrictEqual(p, paths[i])
Expand All @@ -128,15 +126,12 @@ describe('klaw-sync', () => {
})

it('should filter based on both path and stats', () => {
const f1 = path.join(TEST_DIR, 'dir1', 'foo.js')
const f2 = path.join(TEST_DIR, 'dir2', 'dir2_1', 'bar.js')
const f1 = path.join(TEST_DIR, 'foo.js')
const f2 = path.join(TEST_DIR, 'bar.js')
fs.outputFileSync(f1, 'test file 1 contents')
fs.outputFileSync(f2, 'test file 2 contents')
const paths = [
{path: f1, stats: fs.statSync(f1)},
{path: f2, stats: fs.statSync(f2)}
]
const filterFunc = i => path.extname(i.path) === '.js' && i.stats.size > 0
const paths = [{path: f1, stats: fs.statSync(f1)}]
const filterFunc = i => i.path === TEST_DIR || (path.basename(i.path).indexOf('foo') > -1 && i.stats.isFile() && i.stats.size > 0)
const items = klawSync(TEST_DIR, {filter: filterFunc})
assert.strictEqual(items.length, paths.length)
items.forEach((p, i) => {
Expand All @@ -146,64 +141,32 @@ describe('klaw-sync', () => {
})
})

it('should filter but not recurse if noRecurseOnFailedFilter is true', () => {
const dirToIgnore1 = path.join(TEST_DIR, 'node_modules')
const dirToIgnore2 = path.join(dirToIgnore1, 'somepkg')
fs.ensureDirSync(dirToIgnore2)
const paths = [
{path: DIRS[0], stats: fs.statSync(DIRS[0])},
{path: FILES[0], stats: fs.statSync(FILES[0])},
{path: DIRS[1], stats: fs.statSync(DIRS[1])},
{path: DIRS[2], stats: fs.statSync(DIRS[2])},
{path: DIRS[3], stats: fs.statSync(DIRS[3])},
{path: FILES[1], stats: fs.statSync(FILES[1])},
{path: FILES[2], stats: fs.statSync(FILES[2])}
]
const filterFunc = i => i.path.indexOf('node_modules') < 0
const items = klawSync(TEST_DIR, {filter: filterFunc, noRecurseOnFailedFilter: true})
assert.strictEqual(items.length, paths.length)
items.forEach((p, i) => {
assert.deepStrictEqual(p, paths[i])
assert.strictEqual(p.path, paths[i].path)
assert.deepStrictEqual(p.stats, paths[i].stats)
})
})

it('should filter when it is used to ignore items', () => {
const dirToIgnore1 = path.join(TEST_DIR, 'node_modules')
const dirToIgnore2 = path.join(TEST_DIR, '.git')
fs.ensureDirSync(dirToIgnore1)
fs.ensureDirSync(dirToIgnore2)
const paths = [
{path: DIRS[0], stats: fs.statSync(DIRS[0])},
{path: FILES[0], stats: fs.statSync(FILES[0])},
{path: DIRS[1], stats: fs.statSync(DIRS[1])},
{path: DIRS[2], stats: fs.statSync(DIRS[2])},
{path: DIRS[3], stats: fs.statSync(DIRS[3])},
{path: FILES[1], stats: fs.statSync(FILES[1])},
{path: FILES[2], stats: fs.statSync(FILES[2])}
]
const filterFunc = i => i.path.indexOf('node_modules') < 0 && i.path.indexOf('.git') < 0
const items = klawSync(TEST_DIR, {filter: filterFunc, noRecurseOnFailedFilter: true})
assert.strictEqual(items.length, paths.length)
items.forEach((p, i) => {
assert.deepStrictEqual(p, paths[i])
assert.strictEqual(p.path, paths[i].path)
assert.deepStrictEqual(p.stats, paths[i].stats)
it('should ignore hidden directories', () => {
const dir1 = path.join(TEST_DIR, '.dir1')
const dir2 = path.join(TEST_DIR, '.dir2')
fs.ensureDirSync(dir1)
fs.ensureDirSync(dir2)
const filterFunc = i => path.basename(i.path) === '.' || path.basename(i.path)[0] !== '.'
const items = klawSync(TEST_DIR, {filter: filterFunc})
assert(items.length > 0)
items.forEach(p => {
assert(p.path !== dir1)
assert(p.path !== dir2)
})
})

it('should filter and apply opts.nodir', () => {
const f1 = path.join(TEST_DIR, 'dir1', 'foo.js')
const f2 = path.join(TEST_DIR, 'dir2', 'dir2_1', 'bar.js')
const f1 = path.join(TEST_DIR, 'bar.js')
const f2 = path.join(TEST_DIR, 'foo.js')
fs.outputFileSync(f1, 'test file 1 contents')
fs.outputFileSync(f2, 'test file 2 contents')
const paths = [
{path: f1, stats: fs.statSync(f1)},
{path: f2, stats: fs.statSync(f2)}
]
const filterFunc = i => i.stats.size > 0
const filterFunc = i => i.path === TEST_DIR || (i.stats.isFile() && i.stats.size > 0)
const items = klawSync(TEST_DIR, {filter: filterFunc, nodir: true})
items.sort()
assert.strictEqual(items.length, paths.length)
items.forEach((p, i) => {
assert.deepStrictEqual(p, paths[i])
Expand Down Expand Up @@ -285,17 +248,4 @@ describe('klaw-sync', () => {
assert.deepStrictEqual(items, expected)
}
})
/*
describe('custom fs', () => {
let cfs
describe('when opts.fs is memory-fs', () => {
beforeEach(() => {
cfs = new memoryfs()
TEST_DIR = cfs.mkdirpSync()
})
it('should use memory-fs', () => {
})
})
})
*/
})

0 comments on commit 04a9491

Please sign in to comment.