Permalink
Browse files

Added fileutils directly to project in order to avoid external depend…

…ency
  • Loading branch information...
1 parent 5c57f19 commit 2c7463cc970820ece2d277668b28caba930648e6 @lukebayes committed Oct 4, 2011
Showing with 173 additions and 6 deletions.
  1. +4 −4 package.json
  2. +0 −2 runner.js
  3. +169 −0 src/fileutils.js
View
@@ -7,16 +7,16 @@
"author" : {
"name" : "Luke Bayes",
"email" : "lbayes@patternpark.com",
- "url" : "http://lukebayes.com",
+ "url" : "http://lukebayes.com"
},
"repository" : {
"type" : "git",
- "url" : "https://github.com/lukebayes/node-should",
+ "url" : "https://github.com/lukebayes/node-should"
},
"bin" : { "nodeshould" : "./cli.js" },
- "dependencies" : { "fileutils" : ">= 0.0.1" },
"directories" : ["src"],
"main" : "node_should.js",
"test" : "runner.js",
- "engines" : { "node" : ">= 0.4.0" },
+ "engines" : { "node" : ">= 0.4.0" }
}
+
View
@@ -10,5 +10,3 @@ require.paths.unshift('test');
var Runner = require('node_should').Runner;
var runner = new Runner();
runner.run();
-
-
View
@@ -0,0 +1,169 @@
+var fs = require("fs");
+
+/**
+ * Call fileHandler with the file name and file Stat for each file found inside
+ * of the provided directory.
+ *
+ * Call the optionally provided completeHandler with an array of files (mingled
+ * with directories) and an array of Stat objects (one for each of the found
+ * files.
+ *
+ * Following is an example of a simple usage:
+ *
+ * eachFileOrDirectory('test/', function(err, file, stat) {
+ * if (err) throw err;
+ * if (!stat.isDirectory()) {
+ * console.log(">> Found file: " + file);
+ * }
+ * });
+ *
+ * Following is an example that waits for all files and directories to be
+ * scanned and then uses the entire result to do somthing:
+ *
+ * eachFileOrDirectory('test/', null, function(files, stats) {
+ * if (err) throw err;
+ * var len = files.length;
+ * for (var i = 0; i < len; i++) {
+ * if (!stats[i].isDirectory()) {
+ * console.log(">> Found file: " + files[i]);
+ * }
+ * }
+ * });
+ */
+var eachFileOrDirectory = function(directory, fileHandler, completeHandler) {
+ var filesToCheck = 0;
+ var checkedFiles = [];
+ var checkedStats = [];
+
+ directory = (directory) ? directory : './';
+
+ var fullFilePath = function(dir, file) {
+ return dir.replace(/\/$/, '') + '/' + file;
+ };
+
+ var checkComplete = function() {
+ if (filesToCheck == 0 && completeHandler) {
+ completeHandler(null, checkedFiles, checkedStats);
+ }
+ };
+
+ var onFileOrDirectory = function(fileOrDirectory) {
+ filesToCheck++;
+ fs.stat(fileOrDirectory, function(err, stat) {
+ filesToCheck--;
+ if (err) return fileHandler(err);
+ checkedFiles.push(fileOrDirectory);
+ checkedStats.push(stat);
+ fileHandler(null, fileOrDirectory, stat);
+ if (stat.isDirectory()) {
+ onDirectory(fileOrDirectory);
+ }
+ checkComplete();
+ });
+ };
+
+ var onDirectory = function(dir) {
+ filesToCheck++;
+ fs.readdir(dir, function(err, files) {
+ filesToCheck--;
+ if (err) return fileHandler(err);
+ files.forEach(function(file, index) {
+ file = fullFilePath(dir, file);
+ onFileOrDirectory(file);
+ });
+ checkComplete();
+ });
+ }
+
+ onFileOrDirectory(directory);
+};
+
+/**
+ * Recursivly, asynchronously traverse the file system calling the provided
+ * callback for each file (non-directory) found.
+ *
+ * Traversal will begin on the provided path.
+ */
+var eachFile = function(path, callback, completeHandler) {
+ var files = [];
+ var stats = [];
+
+ eachFileOrDirectory(path, function(err, file, stat) {
+ if (err) return callback(err);
+ if (!stat.isDirectory()) {
+ files.push(file);
+ stats.push(stat);
+ if (callback) callback(null, file, stat);
+ }
+ }, function(err) {
+ if (err) return completeHandler(err);
+ if (completeHandler) completeHandler(null, files, stats);
+ });
+};
+
+/**
+ * Works just like eachFile, but it only includes files that match a provided
+ * regular expression.
+ *
+ * eachFileMatching(/_test.js/, 'test', function(err, file, stat) {
+ * if (err) throw err;
+ * console.log(">> Found file: " + file);
+ * });
+ *
+ */
+var eachFileMatching = function(expression, path, callback, completeHandler) {
+ var files = [];
+ var stats = [];
+
+ eachFile(path, function(err, file, stat) {
+ if (err) return callback(err);
+ if (expression.test(file)) {
+ files.push(file);
+ stats.push(stat);
+ if (callback) callback(null, file, stat);
+ }
+ }, function(err) {
+ if (err) return completeHandler(err);
+ completeHandler(null, files, stats);
+ });
+};
+
+/**
+ * Read each file with a file name that matches the provided expression
+ * and was found in the provided path.
+ *
+ * Calls the optionally provided callback for each file found.
+ *
+ * Calls the optionally provided completeHandler when the search is
+ * complete.
+ *
+ * readEachFileMatching(/_test.js/, 'test', function(err, file, stat, content) {
+ * if (err) throw err;
+ * console.log(">> Found file: " + file + " with: " + content.length + " chars");
+ * });
+ */
+var readEachFileMatching = function(expression, path, callback, completeHandler) {
+ var files = [];
+ var contents = [];
+ var stats = [];
+ eachFileMatching(expression, path, function(err, file, stat) {
+ fs.readFile(file, function(err, content) {
+ if (err) return callback(err);
+ files.push(file);
+ contents.push(content);
+ stats.push(stat);
+ if (callback) callback(null, file, stat, content);
+ });
+ }, function(err) {
+ if (err) return completeHandler(err);
+ if (completeHandler) completeHandler(err, files, stats, contents);
+ });
+
+};
+
+exports.eachFile = eachFile;
+exports.eachFileMatching = eachFileMatching;
+exports.eachFileOrDirectory = eachFileOrDirectory;
+exports.readEachFileMatching = readEachFileMatching;
+
+

0 comments on commit 2c7463c

Please sign in to comment.