You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.0 KiB
90 lines
2.0 KiB
'use strict'; |
|
|
|
/** |
|
* Module dependencies |
|
*/ |
|
|
|
var fs = require('fs'); |
|
var path = require('path'); |
|
var isGlob = require('is-glob'); |
|
var resolveDir = require('resolve-dir'); |
|
var detect = require('detect-file'); |
|
var mm = require('micromatch'); |
|
|
|
/** |
|
* @param {String|Array} `pattern` Glob pattern or file path(s) to match against. |
|
* @param {Object} `options` Options to pass to [micromatch]. Note that if you want to start in a different directory than the current working directory, specify the `options.cwd` property here. |
|
* @return {String} Returns the first matching file. |
|
* @api public |
|
*/ |
|
|
|
module.exports = function (patterns, options) { |
|
options = options || {}; |
|
var cwd = path.resolve(resolveDir(options.cwd || '')); |
|
|
|
if (typeof patterns === 'string') { |
|
return lookup(cwd, [patterns], options); |
|
} |
|
|
|
if (!Array.isArray(patterns)) { |
|
throw new TypeError( |
|
'findup-sync expects a string or array as the first argument.' |
|
); |
|
} |
|
|
|
return lookup(cwd, patterns, options); |
|
}; |
|
|
|
function lookup(cwd, patterns, options) { |
|
var len = patterns.length; |
|
var idx = -1; |
|
var res; |
|
|
|
while (++idx < len) { |
|
if (isGlob(patterns[idx])) { |
|
res = matchFile(cwd, patterns[idx], options); |
|
} else { |
|
res = findFile(cwd, patterns[idx], options); |
|
} |
|
if (res) { |
|
return res; |
|
} |
|
} |
|
|
|
var dir = path.dirname(cwd); |
|
if (dir === cwd) { |
|
return null; |
|
} |
|
return lookup(dir, patterns, options); |
|
} |
|
|
|
function matchFile(cwd, pattern, opts) { |
|
var isMatch = mm.matcher(pattern, opts); |
|
var files = tryReaddirSync(cwd); |
|
var len = files.length; |
|
var idx = -1; |
|
|
|
while (++idx < len) { |
|
var name = files[idx]; |
|
var fp = path.join(cwd, name); |
|
if (isMatch(name) || isMatch(fp)) { |
|
return fp; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
function findFile(cwd, filename, options) { |
|
var fp = path.resolve(cwd, filename); |
|
return detect(fp, options); |
|
} |
|
|
|
function tryReaddirSync(fp) { |
|
try { |
|
return fs.readdirSync(fp); |
|
} catch (err) { |
|
// Ignore error |
|
} |
|
/* istanbul ignore next */ |
|
return []; |
|
}
|
|
|