Skip to content

Commit b502f7c

Browse files
committed
[New] add isDirectory
Backport of 698a3e1 to 1.x without the breaking change. See browserify#154.
1 parent c36ba3d commit b502f7c

File tree

5 files changed

+84
-4
lines changed

5 files changed

+84
-4
lines changed

lib/async.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ var defaultIsFile = function isFile(file, cb) {
1515
});
1616
};
1717

18+
var defaultIsDir = function isDirectory(dir, cb) {
19+
fs.stat(dir, function (err, stat) {
20+
if (!err) {
21+
return cb(null, stat.isDirectory());
22+
}
23+
if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false);
24+
return cb(err);
25+
});
26+
};
27+
1828
module.exports = function resolve(x, options, callback) {
1929
var cb = callback;
2030
var opts = options;
@@ -32,6 +42,7 @@ module.exports = function resolve(x, options, callback) {
3242
opts = normalizeOptions(x, opts);
3343

3444
var isFile = opts.isFile || defaultIsFile;
45+
var isDirectory = opts.isDirectory || defaultIsDir;
3546
var readFile = opts.readFile || fs.readFile;
3647

3748
var extensions = opts.extensions || ['.js'];

lib/sync.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ var defaultIsFile = function isFile(file) {
1515
return stat.isFile() || stat.isFIFO();
1616
};
1717

18+
var defaultIsDir = function isDirectory(dir) {
19+
try {
20+
var stat = fs.statSync(dir);
21+
} catch (e) {
22+
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
23+
throw e;
24+
}
25+
return stat.isDirectory();
26+
};
27+
1828
module.exports = function (x, options) {
1929
if (typeof x !== 'string') {
2030
throw new TypeError('Path must be a string.');
@@ -23,6 +33,7 @@ module.exports = function (x, options) {
2333

2434
var isFile = opts.isFile || defaultIsFile;
2535
var readFileSync = opts.readFileSync || fs.readFileSync;
36+
var isDirectory = opts.isDirectory || defaultIsDir;
2637

2738
var extensions = opts.extensions || ['.js'];
2839
var basedir = opts.basedir || path.dirname(caller());

readme.markdown

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ options are:
5959

6060
* opts.isFile - function to asynchronously test whether a file exists
6161

62+
* opts.isDirectory - function to asynchronously test whether a directory exists
63+
6264
* `opts.packageFilter(pkg, pkgfile)` - transform the parsed package.json contents before looking at the "main" field
6365
* pkg - package data
6466
* pkgfile - path to package.json
@@ -101,6 +103,15 @@ default `opts` values:
101103
return cb(err);
102104
});
103105
},
106+
isDirectory: function isDirectory(dir, cb) {
107+
fs.stat(dir, function (err, stat) {
108+
if (!err) {
109+
return cb(null, stat.isDirectory());
110+
}
111+
if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false);
112+
return cb(err);
113+
});
114+
},
104115
moduleDirectory: 'node_modules',
105116
preserveSymlinks: true
106117
}
@@ -121,6 +132,8 @@ options are:
121132

122133
* opts.isFile - function to synchronously test whether a file exists
123134

135+
* opts.isDirectory - function to synchronously test whether a directory exists
136+
124137
* `opts.packageFilter(pkg, dir)` - transform the parsed package.json contents before looking at the "main" field
125138
* pkg - package data
126139
* dir - directory for package.json (Note: the second argument will change to "pkgfile" in v2)
@@ -157,6 +170,15 @@ default `opts` values:
157170
}
158171
return stat.isFile() || stat.isFIFO();
159172
},
173+
isDirectory: function isDirectory(dir) {
174+
try {
175+
var stat = fs.statSync(dir);
176+
} catch (e) {
177+
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
178+
throw e;
179+
}
180+
return stat.isDirectory();
181+
},
160182
moduleDirectory: 'node_modules',
161183
preserveSymlinks: true
162184
}

test/mock.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@ test('mock', function (t) {
88
var files = {};
99
files[path.resolve('/foo/bar/baz.js')] = 'beep';
1010

11+
var dirs = {};
12+
dirs[path.resolve('/foo/bar')] = true;
13+
1114
function opts(basedir) {
1215
return {
1316
basedir: path.resolve(basedir),
1417
isFile: function (file, cb) {
1518
cb(null, Object.prototype.hasOwnProperty.call(files, path.resolve(file)));
1619
},
20+
isDirectory: function (dir, cb) {
21+
cb(null, !!dirs[path.resolve(dir)]);
22+
},
1723
readFile: function (file, cb) {
1824
cb(null, files[path.resolve(file)]);
1925
}
@@ -49,12 +55,18 @@ test('mock from package', function (t) {
4955
var files = {};
5056
files[path.resolve('/foo/bar/baz.js')] = 'beep';
5157

58+
var dirs = {};
59+
dirs[path.resolve('/foo/bar')] = true;
60+
5261
function opts(basedir) {
5362
return {
5463
basedir: path.resolve(basedir),
5564
isFile: function (file, cb) {
5665
cb(null, Object.prototype.hasOwnProperty.call(files, file));
5766
},
67+
isDirectory: function (dir, cb) {
68+
cb(null, !!dirs[path.resolve(dir)]);
69+
},
5870
'package': { main: 'bar' },
5971
readFile: function (file, cb) {
6072
cb(null, files[file]);
@@ -94,12 +106,18 @@ test('mock package', function (t) {
94106
main: './baz.js'
95107
});
96108

109+
var dirs = {};
110+
dirs[path.resolve('/foo')] = true;
111+
97112
function opts(basedir) {
98113
return {
99114
basedir: path.resolve(basedir),
100115
isFile: function (file, cb) {
101116
cb(null, Object.prototype.hasOwnProperty.call(files, path.resolve(file)));
102117
},
118+
isDirectory: function (dir, cb) {
119+
cb(null, !!dirs[path.resolve(dir)]);
120+
},
103121
readFile: function (file, cb) {
104122
cb(null, files[path.resolve(file)]);
105123
}
@@ -122,12 +140,18 @@ test('mock package from package', function (t) {
122140
main: './baz.js'
123141
});
124142

143+
var dirs = {};
144+
dirs[path.resolve('/foo')] = true;
145+
125146
function opts(basedir) {
126147
return {
127148
basedir: path.resolve(basedir),
128149
isFile: function (file, cb) {
129150
cb(null, Object.prototype.hasOwnProperty.call(files, path.resolve(file)));
130151
},
152+
isDirectory: function (dir, cb) {
153+
cb(null, !!dirs[path.resolve(dir)]);
154+
},
131155
'package': { main: 'bar' },
132156
readFile: function (file, cb) {
133157
cb(null, files[path.resolve(file)]);

test/mock_sync.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,20 @@ test('mock', function (t) {
88
var files = {};
99
files[path.resolve('/foo/bar/baz.js')] = 'beep';
1010

11+
var dirs = {};
12+
dirs[path.resolve('/foo/bar')] = true;
13+
1114
function opts(basedir) {
1215
return {
1316
basedir: path.resolve(basedir),
1417
isFile: function (file) {
15-
return Object.prototype.hasOwnProperty.call(files, file);
18+
return Object.prototype.hasOwnProperty.call(files, path.resolve(file));
19+
},
20+
isDirectory: function (dir) {
21+
return !!dirs[path.resolve(dir)];
1622
},
1723
readFileSync: function (file) {
18-
return files[file];
24+
return files[path.resolve(file)];
1925
}
2026
};
2127
}
@@ -48,14 +54,20 @@ test('mock package', function (t) {
4854
main: './baz.js'
4955
});
5056

57+
var dirs = {};
58+
dirs[path.resolve('/foo')] = true;
59+
5160
function opts(basedir) {
5261
return {
5362
basedir: path.resolve(basedir),
5463
isFile: function (file) {
55-
return Object.prototype.hasOwnProperty.call(files, file);
64+
return Object.prototype.hasOwnProperty.call(files, path.resolve(file));
65+
},
66+
isDirectory: function (dir) {
67+
return !!dirs[path.resolve(dir)];
5668
},
5769
readFileSync: function (file) {
58-
return files[file];
70+
return files[path.resolve(file)];
5971
}
6072
};
6173
}

0 commit comments

Comments
 (0)