Spaces:
Paused
Paused
| ; | |
| /** | |
| * Contains `lookupFiles`, which takes some globs/dirs/options and returns a list of files. | |
| * @module | |
| * @private | |
| */ | |
| var fs = require('fs'); | |
| var path = require('path'); | |
| var glob = require('glob'); | |
| var {format} = require('util'); | |
| var errors = require('../errors'); | |
| var createNoFilesMatchPatternError = errors.createNoFilesMatchPatternError; | |
| var createMissingArgumentError = errors.createMissingArgumentError; | |
| var {sQuote, dQuote} = require('../utils'); | |
| const debug = require('debug')('mocha:cli:lookup-files'); | |
| /** | |
| * 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 | |
| */ | |
| const isHiddenOnUnix = pathname => path.basename(pathname).startsWith('.'); | |
| /** | |
| * Determines if pathname has a matching file extension. | |
| * | |
| * Supports multi-part extensions. | |
| * | |
| * @private | |
| * @param {string} pathname - Pathname to check for match. | |
| * @param {string[]} exts - List of file extensions, w/-or-w/o leading period | |
| * @return {boolean} `true` if file extension matches. | |
| * @example | |
| * hasMatchingExtname('foo.html', ['js', 'css']); // false | |
| * hasMatchingExtname('foo.js', ['.js']); // true | |
| * hasMatchingExtname('foo.js', ['js']); // ture | |
| */ | |
| const hasMatchingExtname = (pathname, exts = []) => | |
| exts | |
| .map(ext => (ext.startsWith('.') ? ext : `.${ext}`)) | |
| .some(ext => pathname.endsWith(ext)); | |
| /** | |
| * Lookup file names at the given `path`. | |
| * | |
| * @description | |
| * Filenames are returned in _traversal_ order by the OS/filesystem. | |
| * **Make no assumption that the names will be sorted in any fashion.** | |
| * | |
| * @public | |
| * @alias module:lib/cli.lookupFiles | |
| * @param {string} filepath - Base path to start searching from. | |
| * @param {string[]} [extensions=[]] - File extensions to look for. | |
| * @param {boolean} [recursive=false] - Whether to recurse into subdirectories. | |
| * @return {string[]} An array of paths. | |
| * @throws {Error} if no files match pattern. | |
| * @throws {TypeError} if `filepath` is directory and `extensions` not provided. | |
| */ | |
| module.exports = function lookupFiles( | |
| filepath, | |
| extensions = [], | |
| recursive = false | |
| ) { | |
| const files = []; | |
| let stat; | |
| if (!fs.existsSync(filepath)) { | |
| let pattern; | |
| if (glob.hasMagic(filepath)) { | |
| // Handle glob as is without extensions | |
| pattern = filepath; | |
| } else { | |
| // glob pattern e.g. 'filepath+(.js|.ts)' | |
| const strExtensions = extensions | |
| .map(ext => (ext.startsWith('.') ? ext : `.${ext}`)) | |
| .join('|'); | |
| pattern = `${filepath}+(${strExtensions})`; | |
| debug('looking for files using glob pattern: %s', pattern); | |
| } | |
| files.push(...glob.sync(pattern, {nodir: true})); | |
| if (!files.length) { | |
| throw createNoFilesMatchPatternError( | |
| 'Cannot find any files matching pattern ' + dQuote(filepath), | |
| filepath | |
| ); | |
| } | |
| return files; | |
| } | |
| // Handle file | |
| try { | |
| stat = fs.statSync(filepath); | |
| if (stat.isFile()) { | |
| return filepath; | |
| } | |
| } catch (err) { | |
| // ignore error | |
| return; | |
| } | |
| // Handle directory | |
| fs.readdirSync(filepath).forEach(dirent => { | |
| const pathname = path.join(filepath, dirent); | |
| let stat; | |
| try { | |
| stat = fs.statSync(pathname); | |
| if (stat.isDirectory()) { | |
| if (recursive) { | |
| files.push(...lookupFiles(pathname, extensions, recursive)); | |
| } | |
| return; | |
| } | |
| } catch (ignored) { | |
| return; | |
| } | |
| if (!extensions.length) { | |
| throw createMissingArgumentError( | |
| format( | |
| 'Argument %s required when argument %s is a directory', | |
| sQuote('extensions'), | |
| sQuote('filepath') | |
| ), | |
| 'extensions', | |
| 'array' | |
| ); | |
| } | |
| if ( | |
| !stat.isFile() || | |
| !hasMatchingExtname(pathname, extensions) || | |
| isHiddenOnUnix(pathname) | |
| ) { | |
| return; | |
| } | |
| files.push(pathname); | |
| }); | |
| return files; | |
| }; | |