[Pkg-javascript-commits] [node-findit] 01/03: Imported Upstream version 1.2.0
Andrew Kelley
andrewrk-guest at moszumanska.debian.org
Fri Jun 27 21:51:01 UTC 2014
This is an automated email from the git hooks/post-receive script.
andrewrk-guest pushed a commit to branch master
in repository node-findit.
commit 5439aa67ac65735af1dbe5739859f556ce51733e
Author: Andrew Kelley <superjoe30 at gmail.com>
Date: Fri Jun 27 21:41:34 2014 +0000
Imported Upstream version 1.2.0
---
.travis.yml | 4 +
LICENSE | 18 +++++
example/emitter.js | 16 ++++
index.js | 134 +++++++++++++++++++++++++++++++++
package.json | 31 ++++++++
readme.markdown | 103 +++++++++++++++++++++++++
test/empty.js | 17 +++++
test/foo.js | 57 ++++++++++++++
test/foo/a/b/c/w | 0
test/foo/a/b/z | 0
test/foo/a/y | 0
test/foo/x | 0
test/module.js | 21 ++++++
test/stop.js | 33 ++++++++
test/stop/q/w/c | 0
test/stop/q/w/d | 0
test/stop/q/x | 0
test/stop/q/y | 0
test/stop/q/z/m | 0
test/stop/q/z/n | 0
test/stop/r/a | 0
test/stop/r/b | 0
test/stop/r/c/f/h | 0
test/stop/r/c/g/i | 0
test/symlinks.js | 78 +++++++++++++++++++
test/symlinks/dir1/dangling-symlink | 1 +
test/symlinks/dir1/file1 | 0
test/symlinks/dir1/link-to-dir2 | 1 +
test/symlinks/dir1/link-to-file | 1 +
test/symlinks/dir2/cyclic-link-to-dir1 | 1 +
test/symlinks/dir2/file2 | 0
test/symlinks/file | 0
32 files changed, 516 insertions(+)
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..cc4dba2
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - "0.8"
+ - "0.10"
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..ee27ba4
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,18 @@
+This software is released under the MIT license:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/example/emitter.js b/example/emitter.js
new file mode 100644
index 0000000..4e05b81
--- /dev/null
+++ b/example/emitter.js
@@ -0,0 +1,16 @@
+var finder = require('../')(process.argv[2] || '.');
+var path = require('path');
+
+finder.on('directory', function (dir, stat, stop) {
+ var base = path.basename(dir);
+ if (base === '.git' || base === 'node_modules') stop()
+ else console.log(dir + '/')
+});
+
+finder.on('file', function (file, stat) {
+ console.log(file);
+});
+
+finder.on('link', function (link, stat) {
+ console.log(link);
+});
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..33f4468
--- /dev/null
+++ b/index.js
@@ -0,0 +1,134 @@
+var EventEmitter = require('events').EventEmitter;
+var rfs = require('fs');
+var path = require('path');
+
+module.exports = function walk (dir, opts, emitter, dstat) {
+ if (!opts) opts = {};
+ var fdir = opts._original || dir;
+ opts._original = undefined;
+ var fs = opts.fs || rfs;
+
+ if (!emitter) {
+ emitter = new EventEmitter;
+ emitter.stop = function () {
+ emitter._stopped = true;
+ emitter.emit('stop');
+ };
+ emitter._pending = 0;
+ emitter._seen = {};
+ }
+ emitter._pending ++;
+
+ if (dstat) {
+ var stopped = false;
+ emitter.emit('directory', fdir, dstat, function stop () {
+ stopped = true;
+ });
+ emitter.emit('path', fdir, dstat);
+ if (!stopped) fs.readdir(dir, onreaddir);
+ else check()
+ }
+ else fs.lstat(dir, function onstat (err, stat) {
+ if (emitter._stopped) return;
+ if (err) return finish();
+ emitter._seen[stat.ino || dir] = true;
+
+ if (stat.isSymbolicLink() && opts.followSymlinks) {
+ emitter.emit('link', fdir, stat);
+ fs.readlink(dir, function (err, rfile) {
+ if (emitter._stopped) return;
+ if (err) return finish();
+ var file_ = path.resolve(dir, rfile);
+ emitter.emit('readlink', fdir, file_);
+ fs.lstat(file_, onstat);
+ });
+ }
+ else if (stat.isSymbolicLink()) {
+ emitter.emit('link', fdir, stat);
+ emitter.emit('path', fdir, stat);
+ finish();
+ }
+ else if (stat.isDirectory()) {
+ var stopped = false;
+ emitter.emit('directory', fdir, stat, function stop () {
+ stopped = true;
+ });
+ emitter.emit('path', fdir, stat);
+ if (!stopped) fs.readdir(dir, onreaddir);
+ else check()
+ }
+ else {
+ emitter.emit('file', fdir, stat);
+ emitter.emit('path', fdir, stat);
+ finish();
+ }
+ });
+
+ return emitter;
+
+ function check () {
+ if (-- emitter._pending === 0) finish();
+ }
+
+ function finish () {
+ emitter.emit('end');
+ emitter._seen = null;
+ }
+
+ function onreaddir (err, files) {
+ if (emitter._stopped) return;
+ if (err) return check();
+
+ files.forEach(function (rfile) {
+ emitter._pending ++;
+ var file = path.join(fdir, rfile);
+
+ fs.lstat(file, function (err, stat) {
+ if (emitter._stopped) return;
+ if (err) check()
+ else onstat(file, stat)
+ });
+ });
+ check();
+ }
+
+ function onstat (file, stat, original) {
+ if (emitter._seen[stat.ino || file]) return check();
+ emitter._seen[stat.ino || file] = true;
+
+ if (stat.isDirectory()) {
+ if (original) opts._original = original;
+ walk(file, opts, emitter, stat);
+ check();
+ }
+ else if (stat.isSymbolicLink() && opts.followSymlinks) {
+ emitter.emit('link', file, stat);
+
+ fs.readlink(file, function (err, rfile) {
+ if (emitter._stopped) return;
+ if (err) return check();
+ var file_ = path.resolve(path.dirname(file), rfile);
+
+ emitter.emit('readlink', file, file_);
+ fs.lstat(file_, function (err, stat_) {
+ if (emitter._stopped) return;
+ if (err) return check();
+
+ emitter._pending ++;
+ onstat(file_, stat_, file);
+ check();
+ });
+ });
+ }
+ else if (stat.isSymbolicLink()) {
+ emitter.emit('link', file, stat);
+ emitter.emit('path', file, stat);
+ check();
+ }
+ else {
+ emitter.emit('file', file, stat);
+ emitter.emit('path', file, stat);
+ check();
+ }
+ }
+};
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..fd0d623
--- /dev/null
+++ b/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "findit",
+ "version": "1.2.0",
+ "description": "walk a directory tree recursively with events",
+ "main": "index.js",
+ "devDependencies": {
+ "tap": "~0.4.4",
+ "mkdirp": "~0.3.5"
+ },
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/substack/node-findit.git"
+ },
+ "keywords": [
+ "find",
+ "walk",
+ "directory",
+ "recursive",
+ "tree",
+ "traversal"
+ ],
+ "author": {
+ "name": "James Halliday",
+ "email": "mail at substack.net",
+ "url": "http://substack.net"
+ },
+ "license": "MIT"
+}
diff --git a/readme.markdown b/readme.markdown
new file mode 100644
index 0000000..62a1ec1
--- /dev/null
+++ b/readme.markdown
@@ -0,0 +1,103 @@
+# findit
+
+Recursively walk directory trees. Think `/usr/bin/find`.
+
+[![build status](https://secure.travis-ci.org/substack/node-findit.png)](http://travis-ci.org/substack/node-findit)
+
+# example
+
+``` js
+var finder = require('findit')(process.argv[2] || '.');
+var path = require('path');
+
+finder.on('directory', function (dir, stat, stop) {
+ var base = path.basename(dir);
+ if (base === '.git' || base === 'node_modules') stop()
+ else console.log(dir + '/')
+});
+
+finder.on('file', function (file, stat) {
+ console.log(file);
+});
+
+finder.on('link', function (link, stat) {
+ console.log(link);
+});
+```
+
+# methods
+
+``` js
+var find = require('findit')
+```
+
+## var finder = find(basedir, opts)
+
+Return an event emitter `finder` that performs a recursive walk starting at
+`basedir`.
+
+If you set `opts.followSymlinks`, symlinks will be followed. Otherwise, a
+`'link'` event will fire but symlinked directories will not be walked.
+
+If `basedir` is actually a non-directory regular file, findit emits a single
+"file" event for it then emits "end".
+
+You can optionally specify a custom
+[fs](http://nodejs.org/docs/latest/api/fs.html)
+implementation with `opts.fs`. `opts.fs` should implement:
+
+* `opts.fs.readdir(dir, cb)`
+* `opts.fs.lstat(dir, cb)`
+* `opts.fs.readlink(dir, cb)` - optional if your stat objects from
+`opts.fs.lstat` never return true for `stat.isSymbolicLink()`
+
+## finder.stop()
+
+Stop the traversal. A `"stop"` event will fire and then no more events will
+fire.
+
+# events
+
+## finder.on('path', function (file, stat) {})
+
+For each file, directory, and symlink `file`, this event fires.
+
+## finder.on('file', function (file, stat) {})
+
+For each file, this event fires.
+
+## finder.on('directory', function (dir, stat, stop) {})
+
+For each directory, this event fires with the path `dir`.
+
+Your callback may call `stop()` on the first tick to tell findit to stop walking
+the current directory.
+
+## finder.on('link', function (file, stat) {})
+
+For each symlink, this event fires.
+
+## finder.on('readlink', function (src, dst) {})
+
+Every time a symlink is read when `opts.followSymlinks` is on, this event fires.
+
+## finder.on('end', function () {})
+
+When the recursive walk is complete unless `finder.stop()` was called, this
+event fires.
+
+## finder.on('stop', function () {})
+
+When `finder.stop()` is called, this event fires.
+
+# install
+
+With [npm](https://npmjs.org) do:
+
+```
+npm install findit
+```
+
+# license
+
+MIT
diff --git a/test/empty.js b/test/empty.js
new file mode 100644
index 0000000..a44760b
--- /dev/null
+++ b/test/empty.js
@@ -0,0 +1,17 @@
+var mkdirp = require('mkdirp');
+var test = require('tap').test;
+var find = require('../');
+
+mkdirp.sync(__dirname + '/empty');
+
+test('empty', function (t) {
+ t.plan(1);
+ var w = find(__dirname + '/empty');
+ var files = [];
+ w.on('file', function (file) {
+ files.push(file);
+ });
+ w.on('end', function () {
+ t.deepEqual(files, []);
+ });
+});
diff --git a/test/foo.js b/test/foo.js
new file mode 100644
index 0000000..301dc53
--- /dev/null
+++ b/test/foo.js
@@ -0,0 +1,57 @@
+var find = require('../');
+var test = require('tap').test;
+
+test('foo', function (t) {
+ var finder = find(__dirname + '/foo');
+ var ps = {};
+
+ var paths = []
+ finder.on('path', function (p, stat) {
+ paths.push(p);
+ ps[p] = stat.isDirectory();
+ });
+
+ var dirs = []
+ finder.on('directory', function (dir) {
+ dirs.push(dir);
+ });
+
+ var files = []
+ finder.on('file', function (file) {
+ files.push(file);
+ });
+
+ finder.on('end', function () {
+ var ref = {
+ '' : true,
+ 'a' : true,
+ 'a/b' : true,
+ 'a/b/c' : true,
+ 'x' : false,
+ 'a/y' : false,
+ 'a/b/z' : false,
+ 'a/b/c/w' : false,
+ };
+
+ t.equal(Object.keys(ref).length, Object.keys(ps).length);
+ var count = { dirs : 0, files : 0, paths : 0 };
+
+ Object.keys(ref).forEach(function (key) {
+ var file = (__dirname + '/foo/' + key).replace(/\/$/, '');
+ t.equal(ref[key], ps[file]);
+ if (ref[key]) {
+ t.ok(dirs.indexOf(file) >= 0);
+ count.dirs ++;
+ }
+ else {
+ t.ok(files.indexOf(file) >= 0);
+ count.files ++;
+ }
+ });
+
+ t.deepEqual(count.dirs, dirs.length);
+ t.deepEqual(count.files, files.length);
+ t.deepEqual(paths.sort(), Object.keys(ps).sort());
+ t.end();
+ });
+});
diff --git a/test/foo/a/b/c/w b/test/foo/a/b/c/w
new file mode 100644
index 0000000..e69de29
diff --git a/test/foo/a/b/z b/test/foo/a/b/z
new file mode 100644
index 0000000..e69de29
diff --git a/test/foo/a/y b/test/foo/a/y
new file mode 100644
index 0000000..e69de29
diff --git a/test/foo/x b/test/foo/x
new file mode 100644
index 0000000..e69de29
diff --git a/test/module.js b/test/module.js
new file mode 100644
index 0000000..3fda390
--- /dev/null
+++ b/test/module.js
@@ -0,0 +1,21 @@
+var find = require('../');
+var test = require('tap').test;
+
+test('single file', function (t) {
+ t.plan(2);
+
+ var finder = find(__filename);
+ var files = [];
+ finder.on('file', function (file) {
+ t.equal(file, __filename);
+ files.push(file);
+ });
+
+ finder.on('directory', function (dir) {
+ t.fail(dir);
+ });
+
+ finder.on('end', function () {
+ t.deepEqual(files, [ __filename ]);
+ });
+});
diff --git a/test/stop.js b/test/stop.js
new file mode 100644
index 0000000..4929b11
--- /dev/null
+++ b/test/stop.js
@@ -0,0 +1,33 @@
+var find = require('../');
+var test = require('tap').test;
+var path = require('path');
+
+test('stop', function (t) {
+ t.plan(1);
+
+ var finder = find(__dirname + '/..');
+ var files = [];
+ var stopped = false;
+ finder.on('file', function (file) {
+ files.push(file);
+ if (files.length === 3) {
+ finder.stop();
+ stopped = true;
+ }
+ else if (stopped) {
+ t.fail("files didn't stop");
+ }
+ });
+
+ finder.on('directory', function (dir, stat, stop) {
+ if (stopped) t.fail("directories didn't stop");
+ });
+
+ finder.on('end', function () {
+ t.fail("shouldn't have ended");
+ });
+
+ finder.on('stop', function () {
+ t.equal(files.length, 3);
+ });
+});
diff --git a/test/stop/q/w/c b/test/stop/q/w/c
new file mode 100644
index 0000000..e69de29
diff --git a/test/stop/q/w/d b/test/stop/q/w/d
new file mode 100644
index 0000000..e69de29
diff --git a/test/stop/q/x b/test/stop/q/x
new file mode 100644
index 0000000..e69de29
diff --git a/test/stop/q/y b/test/stop/q/y
new file mode 100644
index 0000000..e69de29
diff --git a/test/stop/q/z/m b/test/stop/q/z/m
new file mode 100644
index 0000000..e69de29
diff --git a/test/stop/q/z/n b/test/stop/q/z/n
new file mode 100644
index 0000000..e69de29
diff --git a/test/stop/r/a b/test/stop/r/a
new file mode 100644
index 0000000..e69de29
diff --git a/test/stop/r/b b/test/stop/r/b
new file mode 100644
index 0000000..e69de29
diff --git a/test/stop/r/c/f/h b/test/stop/r/c/f/h
new file mode 100644
index 0000000..e69de29
diff --git a/test/stop/r/c/g/i b/test/stop/r/c/g/i
new file mode 100644
index 0000000..e69de29
diff --git a/test/symlinks.js b/test/symlinks.js
new file mode 100644
index 0000000..ec393b4
--- /dev/null
+++ b/test/symlinks.js
@@ -0,0 +1,78 @@
+var test = require('tap').test;
+var path = require('path');
+var findit = require('../');
+
+function helper(t, dir, options, callback) {
+ var symlinks = [];
+ var files = [];
+ var dirs = [];
+
+ var finder = findit(dir, options);
+
+ finder.on('link', function (link, stat) {
+ t.ok(stat.isSymbolicLink());
+ symlinks.push(path.basename(link));
+ });
+
+ finder.on('file', function (file, stat) {
+ t.ok(stat.isFile());
+ files.push(path.basename(file));
+ });
+
+ finder.on('directory', function (dir, stat) {
+ t.ok(stat.isDirectory());
+ dirs.push(path.basename(dir));
+ });
+
+ finder.on('error', function (err) {
+ t.fail(err);
+ });
+
+ finder.on('end', function () {
+ symlinks.sort();
+ files.sort();
+ dirs.sort();
+
+ callback({ symlinks: symlinks, files: files, dirs: dirs });
+ });
+}
+
+test('links', function (t) {
+ helper(t, __dirname + '/symlinks/dir1', { followSymlinks: false }, done);
+ function done (data) {
+ t.deepEqual(data.symlinks, [
+ 'dangling-symlink', 'link-to-dir2', 'link-to-file'
+ ]);
+ t.deepEqual(data.files, [ 'file1' ]);
+ t.deepEqual(data.dirs, [ 'dir1' ]);
+ t.end();
+ }
+});
+
+test('follow links', function (t) {
+ helper(t, __dirname + '/symlinks/dir1', { followSymlinks: true }, done);
+
+ function done (data) {
+ t.deepEqual(data.symlinks, [
+ 'cyclic-link-to-dir1', 'dangling-symlink', 'link-to-dir2',
+ 'link-to-file'
+ ]);
+ t.deepEqual(data.files, ['file', 'file1', 'file2']);
+ t.deepEqual(data.dirs, [ 'dir1', 'link-to-dir2' ]);
+ t.end();
+ }
+});
+
+test('parent links', function (t) {
+ helper(t, __dirname + '/symlinks', { followSymlinks: true }, done);
+
+ function done (data) {
+ t.deepEqual(data.symlinks, [
+ 'cyclic-link-to-dir1', 'dangling-symlink', 'link-to-dir2',
+ 'link-to-file'
+ ]);
+ t.deepEqual(data.files, ['file', 'file1', 'file2']);
+ t.deepEqual(data.dirs, [ 'dir1', 'dir2', 'symlinks' ]);
+ t.end();
+ }
+});
diff --git a/test/symlinks/dir1/dangling-symlink b/test/symlinks/dir1/dangling-symlink
new file mode 120000
index 0000000..cfa0a46
--- /dev/null
+++ b/test/symlinks/dir1/dangling-symlink
@@ -0,0 +1 @@
+does-not-exist
\ No newline at end of file
diff --git a/test/symlinks/dir1/file1 b/test/symlinks/dir1/file1
new file mode 100644
index 0000000..e69de29
diff --git a/test/symlinks/dir1/link-to-dir2 b/test/symlinks/dir1/link-to-dir2
new file mode 120000
index 0000000..d014eb4
--- /dev/null
+++ b/test/symlinks/dir1/link-to-dir2
@@ -0,0 +1 @@
+../dir2
\ No newline at end of file
diff --git a/test/symlinks/dir1/link-to-file b/test/symlinks/dir1/link-to-file
new file mode 120000
index 0000000..74bb61d
--- /dev/null
+++ b/test/symlinks/dir1/link-to-file
@@ -0,0 +1 @@
+../file
\ No newline at end of file
diff --git a/test/symlinks/dir2/cyclic-link-to-dir1 b/test/symlinks/dir2/cyclic-link-to-dir1
new file mode 120000
index 0000000..c9f3ab1
--- /dev/null
+++ b/test/symlinks/dir2/cyclic-link-to-dir1
@@ -0,0 +1 @@
+../dir1
\ No newline at end of file
diff --git a/test/symlinks/dir2/file2 b/test/symlinks/dir2/file2
new file mode 100644
index 0000000..e69de29
diff --git a/test/symlinks/file b/test/symlinks/file
new file mode 100644
index 0000000..e69de29
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-findit.git
More information about the Pkg-javascript-commits
mailing list