123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- '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 = cwd ? path.resolve(cwd, filename) : filename;
- return detect(fp, options);
- }
-
- function tryReaddirSync(fp) {
- try {
- return fs.readdirSync(fp);
- } catch (err) {
- // Ignore error
- }
- return [];
- }
|