Skip to content

Commit

Permalink
Update: Cleanup and small improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
jonschlinkert authored and phated committed Dec 28, 2018
1 parent 62d4f4b commit d5b8a65
Show file tree
Hide file tree
Showing 27 changed files with 141 additions and 75 deletions.
2 changes: 1 addition & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = function(grunt) {
options: {
jshintrc: '.jshintrc'
},
all: ['Gruntfile.js', '*.js']
all: ['*.js', 'test/{,support/}*.js']
}
});

Expand Down
28 changes: 16 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var fs = require('fs');
var path = require('path');
var isGlob = require('is-glob');
var resolveDir = require('resolve-dir');
var exists = require('fs-exists-sync');
var mm = require('micromatch');

/**
Expand All @@ -26,9 +27,11 @@ module.exports = function(patterns, options) {
throw new TypeError('findup-sync expects a string or array as the first argument.');
}

var len = patterns.length, i = -1;
while (++i < len) {
var res = lookup(patterns[i], options);
var len = patterns.length;
var idx = -1;

while (++idx < len) {
var res = lookup(patterns[idx], options);
if (res) {
return res;
}
Expand All @@ -39,7 +42,7 @@ module.exports = function(patterns, options) {

function lookup(pattern, options) {
options = options || {};
var cwd = resolveDir(options.cwd || '');
var cwd = path.resolve(resolveDir(options.cwd || ''));
if (isGlob(pattern)) {
return matchFile(cwd, pattern, options);
} else {
Expand All @@ -50,10 +53,11 @@ function lookup(pattern, options) {
function matchFile(cwd, pattern, opts) {
var isMatch = mm.matcher(pattern, opts);
var files = fs.readdirSync(cwd);
var len = files.length, i = -1;
var len = files.length;
var idx = -1;

while (++i < len) {
var name = files[i];
while (++idx < len) {
var name = files[idx];
var fp = path.join(cwd, name);
if (isMatch(name) || isMatch(fp)) {
return fp;
Expand All @@ -68,18 +72,18 @@ function matchFile(cwd, pattern, opts) {
}

function findFile(cwd, filename) {
var fp = cwd ? (cwd + '/' + filename) : filename;
if (fs.existsSync(fp)) {
var fp = cwd ? path.resolve(cwd, filename) : filename;
if (exists(fp)) {
return fp;
}

var segs = cwd.split(path.sep);
var len = segs.length;

while (len--) {
cwd = segs.slice(0, len).join('/');
fp = cwd + '/' + filename;
if (fs.existsSync(fp)) {
cwd = segs.slice(0, len).join(path.sep);
fp = path.resolve(cwd, filename);
if (exists(fp)) {
return fp;
}
}
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,20 @@
"test": "grunt && mocha"
},
"dependencies": {
"fs-exists-sync": "^0.1.0",
"is-glob": "^2.0.1",
"micromatch": "^2.3.7",
"resolve-dir": "^0.1.0"
},
"devDependencies": {
"grunt": "^0.4.5",
"grunt": "^1.0.1",
"grunt-contrib-jshint": "^0.12.0",
"is-absolute": "^0.2.3",
"minimist": "^1.2.0",
"mocha": "^2.4.5",
"normalize-path": "^2.0.1",
"resolve": "^1.1.7",
"user-home": "^2.0.0"
"os-homedir": "^1.0.1",
"resolve": "^1.1.7"
},
"keywords": [
"file",
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/a/a.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a
1 change: 1 addition & 0 deletions test/fixtures/a/b/b.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
b
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/c.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
c
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/d.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
d
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/e/e.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
e
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/e/f/f.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/e/f/file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/e/f/g/file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
g
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/e/f/g/g.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
g
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/e/f/g/h/file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
h
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/e/f/g/h/h.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
h
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/e/f/g/h/i/file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
i
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/e/f/g/h/i/i.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
i
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/e/f/g/h/i/j/file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
j
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/e/f/g/h/i/j/j.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
j
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/e/file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
e
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/d/file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
d
1 change: 1 addition & 0 deletions test/fixtures/a/b/c/file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
c
1 change: 1 addition & 0 deletions test/fixtures/a/b/file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
b
1 change: 1 addition & 0 deletions test/fixtures/a/file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a
1 change: 1 addition & 0 deletions test/fixtures/file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
root
1 change: 1 addition & 0 deletions test/fixtures/root.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
root
51 changes: 51 additions & 0 deletions test/support/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use strict';

var path = require('path');
var normalizePath = require('normalize-path');
var isAbsolute = require('is-absolute');
var resolve = require('resolve');

exports.normalize = function(filepath) {
return filepath ? normalizePath(path.relative('.', filepath)) : null;
};

exports.chdir = function(dir) {
// store current cwd
var orig = process.cwd();
// set cwd to the given `dir`
process.chdir(dir);
return function() {
// restore original `cwd`
process.chdir(orig);
};
};

exports.npm = function npm(name) {
return path.dirname(resolve.sync(name));
};

exports.assert = function(assert) {
assert.isPath = function (filepath) {
assert(filepath);
assert.equal(typeof filepath, 'string');
};

assert.isAbsolute = function (filepath) {
assert(filepath);
assert.equal(typeof filepath, 'string');
assert(isAbsolute(filepath));
};

assert.basename = function (filepath, basename) {
assert(filepath);
assert.equal(typeof filepath, 'string');
assert.equal(path.basename(filepath), basename);
};

assert.dirname = function (filepath, dirname) {
assert(filepath);
assert.equal(typeof filepath, 'string');
assert.equal(path.dirname(path.resolve(filepath)), path.resolve(dirname));
};
};

106 changes: 47 additions & 59 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -1,70 +1,30 @@
'use strict';

require('mocha');
var argv = require('minimist')(process.argv.slice(2));
var fs = require('fs');
var path = require('path');
var assert = require('assert');
var expand = require('resolve-dir');
var norm = require('normalize-path');
var home = require('user-home');
var isAbsolute = require('is-absolute');
var support = require('./support');
support.assert(assert);
var home = require('os-homedir');
var exists = require('fs-exists-sync');
var resolve = require('resolve');
var cwd, actual, opts;

var findup = require('../');
var normalize = support.normalize;
var chdir = support.chdir;
var npm = support.npm;
var cwd;
var actual;

function normalize(fp) {
return fp ? norm(path.relative('.', fp)) : null;
}

if (argv.bench) {
var b = path.join(__dirname, 'benchmark/code', argv.bench);
console.log(b);
findup = require(b);
}

assert.isPath = function (fp, basename) {
assert(fp);
assert.equal(typeof fp, 'string');
};

assert.isAbsolute = function (fp) {
assert(fp);
assert(isAbsolute(fp));
};

assert.exists = function (fp) {
assert(fp);
try {
fs.statSync(fp);
} catch(err) {
assert(fp, err);
}
};

assert.basename = function (fp, basename) {
assert(fp);
assert.equal(path.basename(fp), basename);
};

assert.dirname = function (fp, dirname) {
assert(fp);
assert.equal(path.dirname(path.resolve(fp)), path.resolve(dirname));
};

function npm(name) {
return path.dirname(resolve.sync(name));
}

describe('findup-sync', function () {
before(function () {
fs.writeFileSync(home + '/_aaa.txt', '');
fs.writeFileSync(home + '/_bbb.txt', '');
fs.writeFileSync(home() + '/_aaa.txt', '');
fs.writeFileSync(home() + '/_bbb.txt', '');
});
after(function () {
fs.unlinkSync(home + '/_aaa.txt');
fs.unlinkSync(home + '/_bbb.txt');
fs.unlinkSync(home() + '/_aaa.txt');
fs.unlinkSync(home() + '/_bbb.txt');
});

it('should throw when the first arg is not a string or array:', function(cb) {
Expand All @@ -85,6 +45,34 @@ describe('findup-sync', function () {
assert.equal(normalize(findup('package.json')), 'package.json');
});

it('should find files in a child directory', function () {
var expected = path.resolve(__dirname, 'fixtures/a/b/file.txt');
var restore = chdir(path.resolve(__dirname, 'fixtures/a/b/c/d/e/f/g/h'));

var actual = findup('a/b/file.txt');
assert(actual);
assert(exists(actual));
assert.equal(actual, expected);
restore();
});

it('should find files in a child directory relative to a cwd', function () {
var expectedFile = path.resolve(__dirname, 'fixtures/a/b/file.txt');
var expectedA = path.resolve(__dirname, 'fixtures/a/a.txt');
var tempDir = chdir(path.resolve(__dirname, 'fixtures'));

var actualFile = findup('a/b/file.txt', {cwd: 'a/b/c/d'});
assert(actualFile);
assert(exists(actualFile));
assert.equal(actualFile, expectedFile);

var actualA = findup('a.txt', {cwd: 'a/b/c/d/e/f'});
assert(actualA);
assert(exists(actualA));
assert.equal(actualA, expectedA);
tempDir();
});

it('should support normal (non-glob) file paths:', function () {
var normPath = normalize(findup('package.json', {cwd: path.dirname(resolve.sync('normalize-path'))}));
assert.equal(normPath, 'node_modules/normalize-path/package.json');
Expand Down Expand Up @@ -216,7 +204,7 @@ describe('findup-sync', function () {
});

it('should find files from absolute paths:', function () {
var actual = findup('package.json', { cwd: __dirname })
var actual = findup('package.json', { cwd: __dirname });

assert.basename(actual, 'package.json');
assert.dirname(actual, path.resolve(__dirname, '..'));
Expand All @@ -231,16 +219,16 @@ describe('findup-sync', function () {
});

it('should find files in user home:', function () {
var actual = findup('*', { cwd: home });
var actual = findup('*', { cwd: home() });
assert.isPath(actual);
assert.exists(actual);
assert.dirname(actual, home);
assert(exists(actual));
assert.dirname(actual, home());
});

it('should find files in user home using tilde expansion:', function () {
var actual = findup('*', { cwd: '~' });
assert.isPath(actual);
assert.exists(actual);
assert.dirname(actual, home);
assert(exists(actual));
assert.dirname(actual, home());
});
});

0 comments on commit d5b8a65

Please sign in to comment.