├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── index.js ├── package.json └── test ├── .ignore └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store* 3 | *-link 4 | 5 | npm-debug.log 6 | node_modules 7 | coverage 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | - "0.12" 5 | - "1" 6 | - "2" 7 | - "3" 8 | - "4" 9 | - "6" 10 | - "8" 11 | - "9" 12 | script: "npm run-script test-travis" 13 | after_script: "npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2014 Jonathan Ong me@jongleberry.com 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fs.readdirSyncRecursive 2 | 3 | [![NPM version][npm-image]][npm-url] 4 | [![Build status][travis-image]][travis-url] 5 | [![Test coverage][coveralls-image]][coveralls-url] 6 | [![Dependency Status][david-image]][david-url] 7 | [![License][license-image]][license-url] 8 | [![Downloads][downloads-image]][downloads-url] 9 | [![Gittip][gittip-image]][gittip-url] 10 | 11 | Read a directory recursively. 12 | 13 | ## Install 14 | 15 | ```bash 16 | npm install fs-readdir-recursive 17 | ``` 18 | 19 | ## Example 20 | 21 | ```js 22 | var read = require('fs-readdir-recursive') 23 | read(__dirname) === [ 24 | 'test/test.js', 25 | 'index.js', 26 | 'LICENSE', 27 | 'package.json', 28 | 'README.md' 29 | ] 30 | ``` 31 | 32 | ## API 33 | 34 | ### read(root [, filter]) 35 | 36 | `root` is the directory you wish to scan. `filter` is an optional filter for the files with three params(name, index, dir). By default, filter is: 37 | 38 | ```js 39 | function (name) { 40 | return name[0] !== '.' 41 | } 42 | ``` 43 | 44 | Which basically just ignores `.` files. 45 | 46 | [npm-image]: https://img.shields.io/npm/v/fs-readdir-recursive.svg?style=flat-square 47 | [npm-url]: https://npmjs.org/package/fs-readdir-recursive 48 | [github-tag]: http://img.shields.io/github/tag/fs-utils/fs-readdir-recursive.svg?style=flat-square 49 | [github-url]: https://github.com/fs-utils/fs-readdir-recursive/tags 50 | [travis-image]: https://img.shields.io/travis/fs-utils/fs-readdir-recursive.svg?style=flat-square 51 | [travis-url]: https://travis-ci.org/fs-utils/fs-readdir-recursive 52 | [coveralls-image]: https://img.shields.io/coveralls/fs-utils/fs-readdir-recursive.svg?style=flat-square 53 | [coveralls-url]: https://coveralls.io/r/fs-utils/fs-readdir-recursive 54 | [david-image]: http://img.shields.io/david/fs-utils/fs-readdir-recursive.svg?style=flat-square 55 | [david-url]: https://david-dm.org/fs-utils/fs-readdir-recursive 56 | [license-image]: http://img.shields.io/npm/l/fs-readdir-recursive.svg?style=flat-square 57 | [license-url]: LICENSE 58 | [downloads-image]: http://img.shields.io/npm/dm/fs-readdir-recursive.svg?style=flat-square 59 | [downloads-url]: https://npmjs.org/package/fs-readdir-recursive 60 | [gittip-image]: https://img.shields.io/gratipay/jonathanong.svg?style=flat-square 61 | [gittip-url]: https://gratipay.com/jonathanong/ 62 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | var path = require('path') 3 | 4 | module.exports = read 5 | 6 | function read(root, filter, files, prefix) { 7 | prefix = prefix || '' 8 | files = files || [] 9 | filter = filter || noDotFiles 10 | 11 | var dir = path.join(root, prefix) 12 | if (!fs.existsSync(dir)) return files 13 | if (fs.statSync(dir).isDirectory()) 14 | fs.readdirSync(dir) 15 | .filter(function (name, index) { 16 | return filter(name, index, dir) 17 | }) 18 | .forEach(function (name) { 19 | read(root, filter, files, path.join(prefix, name)) 20 | }) 21 | else 22 | files.push(prefix) 23 | 24 | return files 25 | } 26 | 27 | function noDotFiles(x) { 28 | return x[0] !== '.' 29 | } 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fs-readdir-recursive", 3 | "description": "Recursively read a directory", 4 | "version": "1.1.0", 5 | "scripts": { 6 | "test": "mocha --reporter spec", 7 | "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot", 8 | "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot" 9 | }, 10 | "devDependencies": { 11 | "istanbul": "0", 12 | "mocha": "3", 13 | "should": "*" 14 | }, 15 | "author": { 16 | "name": "Jonathan Ong", 17 | "email": "me@jongleberry.com", 18 | "url": "http://jongleberry.com", 19 | "twitter": "https://twitter.com/jongleberry" 20 | }, 21 | "repository": "fs-utils/fs-readdir-recursive", 22 | "files": [ 23 | "index.js" 24 | ], 25 | "license": "MIT" 26 | } 27 | -------------------------------------------------------------------------------- /test/.ignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fs-utils/fs-readdir-recursive/f810b44477696081ebef9c0d5eafb24005c8e82b/test/.ignore -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | var path = require('path') 3 | var should = require('should') 4 | 5 | var read = require('../') 6 | 7 | describe('fs.readdirSyncRecursive()', function () { 8 | it('should work in the folder', function () { 9 | var files = read(__dirname) 10 | 11 | files.length.should.equal(1) 12 | files[0].should.equal('test.js') 13 | 14 | }) 15 | 16 | it('should work at the root with a filter', function () { 17 | var files = read(path.join(__dirname, '..'), function (name) { 18 | return name[0] !== '.' && name !== 'node_modules' && name !== 'coverage' && name !== 'package-lock.json' 19 | }) 20 | 21 | files.length.should.equal(5) 22 | files.sort().should.eql([ 23 | 'test/test.js', 24 | 'index.js', 25 | 'LICENSE', 26 | 'package.json', 27 | 'README.md' 28 | ].sort()) 29 | 30 | }) 31 | 32 | it('should filter pass dir', function () { 33 | var files = read(path.join(__dirname, '..'), function (name, index, dir) { 34 | return name[0] !== '.' && name !== 'node_modules' && name !== 'coverage' && dir !== __dirname && name !== 'package-lock.json' 35 | }) 36 | 37 | files.length.should.equal(4) 38 | files.sort().should.eql([ 39 | 'index.js', 40 | 'LICENSE', 41 | 'package.json', 42 | 'README.md' 43 | ].sort()) 44 | 45 | }) 46 | 47 | it('should work with the symlinked file', function () { 48 | try { 49 | var linkname = __filename + '-link' 50 | fs.symlinkSync(__filename, linkname, 'file') 51 | 52 | var files = read(__dirname).sort() 53 | 54 | files.length.should.equal(2) 55 | files.should.eql(['test.js', 'test.js-link']) 56 | 57 | } catch (err) { 58 | throw err 59 | } finally { 60 | fs.unlinkSync(linkname) 61 | } 62 | }) 63 | 64 | it('should work in the symlinked directory', function () { 65 | try { 66 | var linkname = __dirname + '-link' 67 | fs.symlinkSync(__dirname, linkname, 'dir') 68 | 69 | var files = read(linkname) 70 | 71 | files.length.should.equal(1) 72 | files[0].should.equal('test.js') 73 | 74 | } catch (err) { 75 | throw err 76 | } finally { 77 | fs.unlinkSync(linkname) 78 | } 79 | }) 80 | 81 | it('should work in the symlinked directory with a filter', function () { 82 | try { 83 | var linkname = path.join(__dirname, '..') + '-link' 84 | fs.symlinkSync(path.join(__dirname, '..'), linkname, 'dir') 85 | 86 | var files = read(linkname, function (name) { 87 | return name[0] !== '.' && name !== 'node_modules' && name !== 'coverage' && name !== 'package-lock.json' 88 | }) 89 | 90 | files.length.should.equal(5) 91 | files.sort().should.eql([ 92 | 'test/test.js', 93 | 'index.js', 94 | 'LICENSE', 95 | 'package.json', 96 | 'README.md' 97 | ].sort()) 98 | } catch (err) { 99 | throw err 100 | } finally { 101 | fs.unlinkSync(linkname) 102 | } 103 | }) 104 | 105 | it('should ignore non-exist symlinked inside', function () { 106 | try { 107 | var linkname = __filename + '-link' 108 | var emptyname = __filename + '-empty' 109 | fs.writeFileSync(emptyname, 'empty') 110 | fs.symlinkSync(emptyname, linkname, 'dir') 111 | fs.unlinkSync(emptyname) 112 | 113 | var files = read(__dirname) 114 | 115 | files.should.eql(['test.js']) 116 | } catch (err) { 117 | throw err 118 | } finally { 119 | fs.unlinkSync(linkname) 120 | } 121 | }) 122 | 123 | it('should return empty array', function () { 124 | read('non-exist-dir').should.eql([]) 125 | }) 126 | }) 127 | --------------------------------------------------------------------------------