This commit is contained in:
Jeff Williams 2017-07-11 15:48:49 -07:00
parent f17395302f
commit 7f8b997d5c
2 changed files with 38 additions and 35 deletions

View File

@ -86,8 +86,8 @@ exports.commonPrefix = function(paths) {
* Retrieve the fully qualified path to the requested resource.
*
* Plugins and templates will be found somewhat similar to how `require()` works, except that the
* directory in which the JSDoc configuration file is will be considered, too, the JSDoc package
* directory will be considered as a fallback, and a globally installed resource won't be found
* directory in which the JSDoc configuration file is will be considered, too; the JSDoc package's
* directory will be considered as a fallback; and a globally installed resource won't be found
* unless it comes with JSDoc.
*
* If the resource path is specified as a path relative to module or package (starting with `.` or
@ -106,19 +106,20 @@ exports.commonPrefix = function(paths) {
* Includes the filename if one was provided.
*/
exports.getResourcePath = function(filepath, filename) {
var pathElems;
var result = null;
var searchDirs = [];
function pathExists(_path) {
function directoryExists(dir) {
var stats;
try {
fs.readdirSync(_path);
stats = fs.statSync(dir);
return stats.isDirectory();
}
catch (e) {
return false;
}
return true;
}
// resources that are installed modules may not have been specified with a filepath
@ -126,18 +127,16 @@ exports.getResourcePath = function(filepath, filename) {
filepath = filename;
filename = undefined;
}
pathElems = filepath.split(path.sep);
// Special case `node_modules/foo`, to accommodate this legacy workaround advertised by
// third-party plugin and template authors
if (pathElems[0] === 'node_modules') {
pathElems.unshift('.');
filepath = pathElems.join(path.sep);
// third-party plugin and template authors.
if ( /^node_modules\//.test(filepath) ) {
filepath = path.join('.', filepath);
}
// search in different sets of directories depending on whether filepath is expressly relative
// to "current" directory or not
searchDirs = pathElems[0].indexOf('.') === 0 ?
searchDirs = /^\./.test(filepath) ?
// look first in "current" (where JSDoc was executed), then in directory of config, and
// _only then_ in JSDoc's directory
[env.pwd, path.dirname(env.opts.configure || ''), env.dirname] :
@ -147,14 +146,17 @@ exports.getResourcePath = function(filepath, filename) {
path.join(path.dirname(env.opts.configure || ''), 'node_modules'),
env.dirname];
// absolute paths are normalized by path.resolve on the first pass
searchDirs.forEach(function(_path) {
if (!result && _path) {
_path = path.resolve(_path, filepath);
if ( pathExists(_path) ) {
result = _path;
searchDirs.some(function(dir) {
if (dir) {
dir = path.resolve(dir, filepath);
if ( directoryExists(dir) ) {
result = dir;
return true;
}
}
return false;
});
if (result) {

View File

@ -157,6 +157,7 @@ describe('jsdoc/path', function() {
});
it('resolves relative to ./ path that exists', function() {
// `path.join` discards the `.`, so we join with `path.sep` instead
var p = ['.', 'util'].join(path.sep);
var resolved = path.getResourcePath(p);
@ -165,7 +166,7 @@ describe('jsdoc/path', function() {
});
it('resolves relative to ../ path that exists', function() {
var p = ['..', 'jsdoc', 'util'].join(path.sep);
var p = path.join('..', 'jsdoc', 'util');
var resolved = path.getResourcePath(p);
expect(resolved).not.toBeNull();
@ -173,7 +174,7 @@ describe('jsdoc/path', function() {
});
it('resolves relative to ../ path that exists in ../ and package', function() {
var prel = ['..', 'plugins'].join(path.sep);
var prel = path.join('..', 'plugins');
var pabs = 'plugins';
var resolved = path.getResourcePath(prel);
@ -184,7 +185,7 @@ describe('jsdoc/path', function() {
});
it('resolves relative to . path that exists in package', function() {
var p = ['.', 'plugins'].join(path.sep);
var p = path.join('.', 'plugins');
var resolved = path.getResourcePath(p);
expect(resolved).not.toBeNull();
@ -192,7 +193,7 @@ describe('jsdoc/path', function() {
});
it('resolves path using node_modules/', function() {
var p = ['node_modules', 'marked'].join(path.sep);
var p = path.join('node_modules', 'marked');
var resolved = path.getResourcePath( path.dirname(p), path.basename(p) );
expect(resolved).not.toBeNull();
@ -208,11 +209,11 @@ describe('jsdoc/path', function() {
});
it('leaves an absolute path as is', function() {
var p = path.resolve([env.dirname, 'anything'].join(path.sep));
var p = path.resolve( path.join(env.dirname, 'anything') );
var resolved = path.getResourcePath(path.dirname(p), 'anything');
expect(resolved).not.toBeNull();
expect( p ).toEqual( resolved );
expect(p).toBe(resolved);
});
});
});