├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── index.js ├── package.json └── test ├── index.js └── nested ├── a ├── b │ ├── .hidden1 │ ├── file1.txt │ └── file2.js └── file1.txt ├── x └── .hidden2 └── y └── z └── file.conf /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | 3 | # Logs 4 | logs 5 | *.log 6 | 7 | # Runtime data 8 | pids 9 | *.pid 10 | *.seed 11 | 12 | # Directory for instrumented libs generated by jscoverage/JSCover 13 | lib-cov 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 19 | .grunt 20 | 21 | # Compiled binary addons (http://nodejs.org/api/addons.html) 22 | build/Release 23 | 24 | # Dependency directory 25 | # Commenting this out is preferred by some people, see 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 27 | node_modules 28 | 29 | # Users Environment Variables 30 | .lock-wscript 31 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .idea 2 | 3 | # Logs 4 | logs 5 | *.log 6 | 7 | # Runtime data 8 | pids 9 | *.pid 10 | *.seed 11 | 12 | # Directory for instrumented libs generated by jscoverage/JSCover 13 | lib-cov 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 19 | .grunt 20 | 21 | # Compiled binary addons (http://nodejs.org/api/addons.html) 22 | build/Release 23 | 24 | # Dependency directory 25 | # Commenting this out is preferred by some people, see 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 27 | node_modules 28 | 29 | # Users Environment Variables 30 | .lock-wscript 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jeremy Battle 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | recursive-readdir-sync 2 | ====================== 3 | NodeJS library to recursively read a directory path's contents synchronously 4 | 5 | A simple Node module for synchronously listing all files in a directory, or in any subdirectories. 6 | 7 | It does not list directories themselves. 8 | 9 | This library uses synchronous filesystem calls. That means this library uses **BLOCKING** calls. Keep that in mind 10 | when using it. 11 | 12 | Install 13 | ------- 14 | 15 | ``` 16 | npm install recursive-readdir-sync 17 | ``` 18 | 19 | Example 20 | ------- 21 | ```javascript 22 | var recursiveReadSync = require('recursive-readdir-sync') 23 | , files 24 | ; 25 | 26 | try { 27 | files = recursiveReadSync('/your/path/here'); 28 | } catch(err){ 29 | if(err.errno === 34){ 30 | console.log('Path does not exist'); 31 | } else { 32 | //something unrelated went wrong, rethrow 33 | throw err; 34 | } 35 | } 36 | 37 | console.log('Files array:', files); 38 | 39 | //loop over resulting files 40 | for(var i = 0, len = files.length; i < len; i++){ 41 | console.log('Found: %s', files[i]); 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | , p = require('path') 3 | ; 4 | 5 | // how to know when you are done? 6 | function recursiveReaddirSync(path) { 7 | var list = [] 8 | , files = fs.readdirSync(path) 9 | , stats 10 | ; 11 | 12 | files.forEach(function (file) { 13 | stats = fs.lstatSync(p.join(path, file)); 14 | if(stats.isDirectory()) { 15 | list = list.concat(recursiveReaddirSync(p.join(path, file))); 16 | } else { 17 | list.push(p.join(path, file)); 18 | } 19 | }); 20 | 21 | return list; 22 | } 23 | 24 | module.exports = recursiveReaddirSync; 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "recursive-readdir-sync", 3 | "version": "1.0.6", 4 | "description": "NodeJS library to recursively read a directory path's contents synchronously", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "mocha" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/battlejj/recursive-readdir-sync" 12 | }, 13 | "keywords": [ 14 | "readdir", 15 | "recursive", 16 | "readdir", 17 | "directory", 18 | "sync", 19 | "read", 20 | "sync" 21 | ], 22 | "author": "Jeremy Battle", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/battlejj/recursive-readdir-sync/issues" 26 | }, 27 | "devDependencies": { 28 | "chai": "^1.9.1", 29 | "lodash": "^4.17.15", 30 | "mocha": "^2.1.0" 31 | }, 32 | "homepage": "https://github.com/battlejj/recursive-readdir-sync" 33 | } 34 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | var chai = require('chai') 2 | , expect = chai.expect 3 | , _ = require('lodash') 4 | , path = require('path') 5 | , recursiveReaddirSync = require('../index') 6 | ; 7 | 8 | describe('Functionality testing.', function(){ 9 | //Files we should find in or path 10 | var expectedFiles = [ 11 | './nested/a/file1.txt', 12 | './nested/a/b/file1.txt', 13 | './nested/a/b/file2.js', 14 | './nested/a/b/.hidden1', 15 | './nested/x/.hidden2', 16 | './nested/y/z/file.conf' 17 | ]; 18 | 19 | expectedFiles = _.map(expectedFiles, function(f){ 20 | return path.resolve(__dirname, f); 21 | }); 22 | 23 | //Directories should not be listed in the results only files. 24 | var unexpectedFiles = [ 25 | './nested/empty' 26 | ]; 27 | 28 | unexpectedFiles = _.map(unexpectedFiles, function(f){ 29 | return path.resolve(__dirname, f); 30 | }); 31 | 32 | var results = recursiveReaddirSync(__dirname + '/nested'); 33 | 34 | it('should return an array with length equal to that of expectedFiles', function(){ 35 | expect(results).to.have.length(expectedFiles.length); 36 | }); 37 | 38 | it('should find all nested files in the folder structure', function(){ 39 | expect(_.xor(results, expectedFiles)).to.have.length(0); 40 | }); 41 | 42 | it('should not contain empty folders', function(){ 43 | expect(results).to.not.include.members(unexpectedFiles); 44 | }); 45 | 46 | }); 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /test/nested/a/b/.hidden1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlejj/recursive-readdir-sync/6cd4f26a5d8c49d66cfbe84328db821023d2a5fb/test/nested/a/b/.hidden1 -------------------------------------------------------------------------------- /test/nested/a/b/file1.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlejj/recursive-readdir-sync/6cd4f26a5d8c49d66cfbe84328db821023d2a5fb/test/nested/a/b/file1.txt -------------------------------------------------------------------------------- /test/nested/a/b/file2.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlejj/recursive-readdir-sync/6cd4f26a5d8c49d66cfbe84328db821023d2a5fb/test/nested/a/b/file2.js -------------------------------------------------------------------------------- /test/nested/a/file1.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlejj/recursive-readdir-sync/6cd4f26a5d8c49d66cfbe84328db821023d2a5fb/test/nested/a/file1.txt -------------------------------------------------------------------------------- /test/nested/x/.hidden2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlejj/recursive-readdir-sync/6cd4f26a5d8c49d66cfbe84328db821023d2a5fb/test/nested/x/.hidden2 -------------------------------------------------------------------------------- /test/nested/y/z/file.conf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/battlejj/recursive-readdir-sync/6cd4f26a5d8c49d66cfbe84328db821023d2a5fb/test/nested/y/z/file.conf --------------------------------------------------------------------------------