Skip to content

Instantly share code, notes, and snippets.

@JosephPecoraro
Created February 23, 2010 08:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JosephPecoraro/312008 to your computer and use it in GitHub Desktop.
Save JosephPecoraro/312008 to your computer and use it in GitHub Desktop.
From f1c3f11113d3e4f75b6addb56e67b3b7ec8076f3 Mon Sep 17 00:00:00 2001
From: Joseph Pecoraro <joepeck02@gmail.com>
Date: Tue, 23 Feb 2010 00:41:00 -0800
Subject: [PATCH] Added fs.glob and fs.globSync.
---
doc/api.txt | 10 ++++++
src/node.js | 61 +++++++++++++++++++++++++++++++++-----
test/mjsunit/test-fs-glob.js | 46 ++++++++++++++++++++++++++++
test/mjsunit/test-readdir.js | 1 +
4 files changed, 110 insertions(+), 8 deletions(-)
create mode 100644 test/mjsunit/fixtures/glob/a.txt
create mode 100644 test/mjsunit/fixtures/glob/b.txt
create mode 100644 test/mjsunit/fixtures/glob/c.js
create mode 100644 test/mjsunit/test-fs-glob.js
diff --git a/doc/api.txt b/doc/api.txt
index 4ea7c5a..cfbbdbb 100644
--- a/doc/api.txt
+++ b/doc/api.txt
@@ -666,6 +666,16 @@ Synchronous readdir(3). Returns an array of filenames excluding +"."+ and
+".."+.
++fs.glob(glob, path, callback)+ ::
+Asynchronous glob. Reads the contents of the given directory +path+, and filters
+the results based on the provided glob string. The callback gets two arguments
++(err, files)+ where +files+ is an array of the names of the files in the
+directory matching the glob.
+
++fs.globSync(glob, path)+ ::
+Synchronous glob.
+
+
+fs.close(fd, callback)+ ::
Asynchronous close(2).
No arguments other than a possible exception are given to the completion callback.
diff --git a/src/node.js b/src/node.js
index 32f3b6d..8aa3b7e 100644
--- a/src/node.js
+++ b/src/node.js
@@ -39,7 +39,7 @@ node.dns.createConnection = removed("node.dns.createConnection() has moved. Use
/**********************************************************************/
-// Module
+// Module
var internalModuleCache = {};
@@ -373,7 +373,7 @@ function debug (x) {
var fsModule = createInternalModule("fs", function (exports) {
exports.Stats = process.Stats;
-
+
// Used by fs.open and friends
function stringToFlags(flag) {
// Only mess with strings
@@ -385,7 +385,7 @@ var fsModule = createInternalModule("fs", function (exports) {
case "r+": return process.O_RDWR;
case "w": return process.O_CREAT | process.O_TRUNC | process.O_WRONLY;
case "w+": return process.O_CREAT | process.O_TRUNC | process.O_RDWR;
- case "a": return process.O_APPEND | process.O_CREAT | process.O_WRONLY;
+ case "a": return process.O_APPEND | process.O_CREAT | process.O_WRONLY;
case "a+": return process.O_APPEND | process.O_CREAT | process.O_RDWR;
default: throw new Error("Unknown file open flag: " + flag);
}
@@ -486,6 +486,51 @@ var fsModule = createInternalModule("fs", function (exports) {
process.fs.lstat(path, callback || noop);
};
+ function readdirGlobHandler(err, files, glob, callback) {
+ if (err) {
+ if (callback) callback(err);
+ } else {
+ files = files.filter(function (file) {
+ var globIndex = 0, globLen = glob.length;
+ var fileIndex = 0, fileLen = file.length;
+ while (globIndex < globLen) {
+ var globChar = glob[globIndex++];
+ if (globChar === '*') {
+ var stopChar = glob[globIndex++];
+ if (stopChar === undefined)
+ return true;
+ while (fileIndex < fileLen) {
+ if (stopChar === file[fileIndex++]) {
+ break;
+ }
+ }
+ } else if (globChar === '?') {
+ fileIndex++;
+ } else if (globChar !== file[fileIndex++]) {
+ return false;
+ }
+ }
+ return (fileIndex === fileLen);
+ });
+
+ if (callback)
+ callback(null, files);
+ else
+ return files;
+ }
+ }
+
+ exports.glob = function (glob, dir, callback) {
+ exports.readdir(dir, function(err, files) {
+ readdirGlobHandler(err, files, glob, callback);
+ });
+ };
+
+ exports.globSync = function (glob, dir) {
+ var files = exports.readdirSync(dir);
+ return readdirGlobHandler(false, files, glob);
+ };
+
exports.stat = function (path, callback) {
process.fs.stat(path, callback || noop);
};
@@ -529,11 +574,11 @@ var fsModule = createInternalModule("fs", function (exports) {
exports.unlinkSync = function (path) {
return process.fs.unlink(path);
};
-
+
exports.chmod = function (path, mode, callback) {
process.fs.chmod(path, mode, callback || noop);
};
-
+
exports.chmodSync = function (path, mode) {
return process.fs.chmod(path, mode);
};
@@ -566,7 +611,7 @@ var fsModule = createInternalModule("fs", function (exports) {
}
});
};
-
+
exports.writeFileSync = function (path, data, encoding) {
encoding = encoding || "utf8"; // default to utf8
var fd = exports.openSync(path, "w");
@@ -577,7 +622,7 @@ var fsModule = createInternalModule("fs", function (exports) {
}
exports.closeSync(fd);
};
-
+
exports.cat = function () {
throw new Error("fs.cat is deprecated. Please use fs.readFile instead.");
};
@@ -604,7 +649,7 @@ var fsModule = createInternalModule("fs", function (exports) {
var callback = (typeof(callback_) == 'function' ? callback_ : null);
exports.open(path, 'r', 0666, function (err, fd) {
if (err) {
- if (callback) callback(err);
+ if (callback) callback(err);
} else {
readAll(fd, 0, "", encoding, callback);
}
diff --git a/test/mjsunit/fixtures/glob/a.txt b/test/mjsunit/fixtures/glob/a.txt
new file mode 100644
index 0000000..e69de29
diff --git a/test/mjsunit/fixtures/glob/b.txt b/test/mjsunit/fixtures/glob/b.txt
new file mode 100644
index 0000000..e69de29
diff --git a/test/mjsunit/fixtures/glob/c.js b/test/mjsunit/fixtures/glob/c.js
new file mode 100644
index 0000000..e69de29
diff --git a/test/mjsunit/test-fs-glob.js b/test/mjsunit/test-fs-glob.js
new file mode 100644
index 0000000..5a6a9fe
--- /dev/null
+++ b/test/mjsunit/test-fs-glob.js
@@ -0,0 +1,46 @@
+process.mixin(require("./common"));
+
+var got_error = false;
+var success_count = 0;
+var globFixturesDir = path.join(fixturesDir, "glob");
+
+fs.glob("*", globFixturesDir, function(err, globFiles) {
+ if (err) got_error = true;
+ fs.readdir(globFixturesDir, function(err, readdirFiles) {
+ if (err) got_error = true;
+ assert.equal(globFiles.length, readdirFiles.length);
+ assert.equal(3, globFiles.length);
+ assert.deepEqual(globFiles, readdirFiles);
+ success_count++;
+ });
+});
+
+fs.glob("*.txt", globFixturesDir, function(err, files) {
+ if (err) got_error = true;
+ assert.equal(true, files.indexOf('a.txt') !== -1);
+ assert.equal(true, files.indexOf('b.txt') !== -1);
+ assert.equal(false, files.indexOf('c.js') !== -1);
+ success_count++;
+});
+
+fs.glob("*.??", globFixturesDir, function(err, files) {
+ if (err) got_error = true;
+ assert.equal(false, files.indexOf('a.txt') !== -1);
+ assert.equal(false, files.indexOf('b.txt') !== -1);
+ assert.equal(true, files.indexOf('c.js') !== -1);
+ success_count++;
+});
+
+try {
+ var files = fs.globSync("*.txt", globFixturesDir);
+ p(files);
+ assert.equal(true, files.indexOf('a.txt') !== -1);
+ assert.equal(true, files.indexOf('b.txt') !== -1);
+ assert.equal(false, files.indexOf('c.js') !== -1);
+ success_count++;
+} catch (e) { got_error = true; p(e); }
+
+process.addListener("exit", function () {
+ assert.equal(4, success_count);
+ assert.equal(false, got_error);
+});
diff --git a/test/mjsunit/test-readdir.js b/test/mjsunit/test-readdir.js
index 4ded485..5edc969 100644
--- a/test/mjsunit/test-readdir.js
+++ b/test/mjsunit/test-readdir.js
@@ -6,6 +6,7 @@ var files = ['a.js'
, 'b'
, 'cycles'
, 'echo.js'
+ , 'glob'
, 'multipart.js'
, 'nested-index'
, 'print-chars.js'
--
1.6.3.rc2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment