Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor lookupFiles and files #3722

Merged
merged 13 commits into from Feb 13, 2019
Merged
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
85 changes: 63 additions & 22 deletions lib/utils.js
Expand Up @@ -9,11 +9,10 @@
* Module dependencies.
*/

var debug = require('debug')('mocha:watch');
var fs = require('fs');
var glob = require('glob');
var path = require('path');
var join = path.join;
var debug = require('debug')('mocha:watch');
plroebuck marked this conversation as resolved.
Show resolved Hide resolved
var glob = require('glob');
var he = require('he');
var errors = require('./errors');
var createNoFilesMatchPatternError = errors.createNoFilesMatchPatternError;
Expand Down Expand Up @@ -92,24 +91,22 @@ function ignored(path) {
*
* @private
* @param {string} dir
* @param {string[]} [ext=['.js']]
* @param {string[]} [exts=['js']]
* @param {Array} [ret=[]]
* @return {Array}
*/
exports.files = function(dir, ext, ret) {
exports.files = function(dir, exts, ret) {
ret = ret || [];
ext = ext || ['js'];

var re = new RegExp('\\.(' + ext.join('|') + ')$');
exts = exts || ['js'];

fs.readdirSync(dir)
.filter(ignored)
.forEach(function(path) {
path = join(dir, path);
if (fs.lstatSync(path).isDirectory()) {
exports.files(path, ext, ret);
} else if (path.match(re)) {
ret.push(path);
.forEach(function(dirent) {
var pathname = path.join(dir, dirent);
if (fs.lstatSync(pathname).isDirectory()) {
exports.files(pathname, exts, ret);
} else if (hasMatchingExtname(pathname, exts)) {
ret.push(pathname);
}
});

Expand Down Expand Up @@ -506,6 +503,40 @@ exports.canonicalize = function canonicalize(value, stack, typeHint) {
return canonicalizedObj;
};

/**
* Determines if pathname has a matching file extension.
*
* @private
* @param {string} pathname - Pathname to check for match.
* @param {string[]} exts - List of file extensions (sans period).
* @return {boolean} whether file extension matches.
* @example
* hasMatchingExtname('foo.html', ['js', 'css']); // => false
*/
function hasMatchingExtname(pathname, exts) {
plroebuck marked this conversation as resolved.
Show resolved Hide resolved
var re = new RegExp('\\.(?:' + exts.join('|') + ')$');
return re.test(path.extname(pathname));
}

/**
* Determines if pathname would be a "hidden" file (or directory) on UN*X.
*
* @description
* On UN*X, pathnames beginning with a full stop (aka dot) are hidden during
* typical usage. Dotfiles, plain-text configuration files, are prime examples.
*
* @see {@link http://xahlee.info/UnixResource_dir/writ/unix_origin_of_dot_filename.html|Origin of Dot File Names}
*
* @private
* @param {string} pathname - Pathname to check for match.
* @return {boolean} whether pathname would be considered a hidden file.
* @example
* isHiddenOnUnix('.profile'); // => true
*/
function isHiddenOnUnix(pathname) {
return path.basename(pathname)[0] === '.';
}

/**
* Lookup file names at the given `path`.
*
Expand All @@ -523,11 +554,13 @@ exports.canonicalize = function canonicalize(value, stack, typeHint) {
*/
exports.lookupFiles = function lookupFiles(filepath, extensions, recursive) {
var files = [];
var stat;

if (!fs.existsSync(filepath)) {
if (fs.existsSync(filepath + '.js')) {
filepath += '.js';
} else {
// Handle glob
files = glob.sync(filepath);
if (!files.length) {
throw createNoFilesMatchPatternError(
Expand All @@ -539,8 +572,9 @@ exports.lookupFiles = function lookupFiles(filepath, extensions, recursive) {
}
}

// Handle file
try {
var stat = fs.statSync(filepath);
stat = fs.statSync(filepath);
if (stat.isFile()) {
return filepath;
}
Expand All @@ -549,13 +583,16 @@ exports.lookupFiles = function lookupFiles(filepath, extensions, recursive) {
return;
}

fs.readdirSync(filepath).forEach(function(file) {
file = path.join(filepath, file);
// Handle directory
fs.readdirSync(filepath).forEach(function(dirent) {
var pathname = path.join(filepath, dirent);
var stat;

try {
var stat = fs.statSync(file);
stat = fs.statSync(pathname);
if (stat.isDirectory()) {
if (recursive) {
files = files.concat(lookupFiles(file, extensions, recursive));
files = files.concat(lookupFiles(pathname, extensions, recursive));
}
return;
}
Expand All @@ -570,11 +607,15 @@ exports.lookupFiles = function lookupFiles(filepath, extensions, recursive) {
'array'
);
}
var re = new RegExp('\\.(?:' + extensions.join('|') + ')$');
if (!stat.isFile() || !re.test(file) || path.basename(file)[0] === '.') {

if (
!stat.isFile() ||
!hasMatchingExtname(pathname, extensions) ||
isHiddenOnUnix(pathname)
) {
return;
}
files.push(file);
files.push(pathname);
});

return files;
Expand Down