Code coverage report for master/lib/jsdoc/path.js

Statements: 70.21% (33 / 47)      Branches: 56.76% (21 / 37)      Functions: 50% (3 / 6)      Lines: 70.21% (33 / 47)      Ignored: none     

All files » master/lib/jsdoc/ » path.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135            1 1 1 1   1 21     21       21   21   12     12 86 6 6         21                                       1 18   18   18     18 3 3 3     3     15       15 8     15     18                                   1     1                                                       1 15    
/**
 * Extended version of the standard `path` module.
 * @module jsdoc/path
 */
'use strict';
 
var env = require('jsdoc/env');
var fs = require('fs');
var path = require('path');
var runtime = require('jsdoc/util/runtime');
 
function prefixReducer(previousPath, current) {
    var currentPath = [];
 
    // if previousPath is defined, but has zero length, there's no common prefix; move along
    Iif (previousPath && !previousPath.length) {
        return currentPath;
    }
 
    currentPath = path.resolve(env.pwd, current).split(path.sep) || [];
 
    if (previousPath && currentPath.length) {
        // remove chunks that exceed the previous path's length
        currentPath = currentPath.slice(0, previousPath.length);
 
        // if a chunk doesn't match the previous path, remove everything from that chunk on
        for (var i = 0, l = currentPath.length; i < l; i++) {
            if (currentPath[i] !== previousPath[i]) {
                currentPath.splice(i, currentPath.length - i);
                break;
            }
        }
    }
 
    return currentPath;
}
 
/**
 * Find the common prefix for an array of paths. If there is a common prefix, a trailing separator
 * is appended to the prefix. Relative paths are resolved relative to the current working directory.
 *
 * For example, assuming that the current working directory is `/Users/jsdoc`:
 *
 * + For the single path `foo/bar/baz/qux.js`, the common prefix is `foo/bar/baz/`.
 * + For paths `foo/bar/baz/qux.js`, `foo/bar/baz/quux.js`, and `foo/bar/baz.js`, the common prefix
 * is `/Users/jsdoc/foo/bar/`.
 * + For paths `../jsdoc/foo/bar/baz/qux/quux/test.js`, `/Users/jsdoc/foo/bar/bazzy.js`, and
 * `../../Users/jsdoc/foo/bar/foobar.js`, the common prefix is `/Users/jsdoc/foo/bar/`.
 * + For paths `foo/bar/baz/qux.js` and `../../Library/foo/bar/baz.js`, there is no common prefix,
 * and an empty string is returned.
 *
 * @param {Array.<string>} paths - The paths to search for a common prefix.
 * @return {string} The common prefix, or an empty string if there is no common prefix.
 */
exports.commonPrefix = function(paths) {
    var segments;
 
    var prefix = '';
 
    paths = paths || [];
 
    // if there's only one path, its resolved dirname (plus a trailing slash) is the common prefix
    if (paths.length === 1) {
        prefix = path.resolve(env.pwd, paths[0]);
        Eif ( path.extname(prefix) ) {
            prefix = path.dirname(prefix);
        }
 
        prefix += path.sep;
    }
    else {
        segments = paths.reduce(prefixReducer, undefined) || [];
 
        // if there's anything left (other than a placeholder for a leading slash), add a
        // placeholder for a trailing slash
        if ( segments.length && (segments.length > 1 || segments[0] !== '') ) {
            segments.push('');
        }
 
        prefix = segments.join(path.sep);
    }
 
    return prefix;
};
 
/**
 * Retrieve the fully qualified path to the requested resource.
 *
 * If the resource path is specified as a relative path, JSDoc searches for the path in the
 * directory where the JSDoc configuration file is located, then in the current working directory,
 * and finally in the JSDoc directory.
 *
 * If the resource path is specified as a fully qualified path, JSDoc uses the path as-is.
 *
 * @param {string} filepath - The path to the requested resource. May be an absolute path; a path
 * relative to the JSDoc directory; or a path relative to the current working directory.
 * @param {string} [filename] - The filename of the requested resource.
 * @return {string} The fully qualified path (or, on Rhino, a URI) to the requested resource.
 * Includes the filename if one was provided.
 */
exports.getResourcePath = function(filepath, filename) {
    var result = null;
 
    function pathExists(_path) {
        try {
            fs.readdirSync(_path);
        }
        catch(e) {
            return false;
        }
 
        return true;
    }
 
    // absolute paths are normalized by path.resolve on the first pass
    [path.dirname(env.opts.configure || ''), env.pwd, env.dirname].forEach(function(_path) {
        if (!result && _path) {
            _path = path.resolve(_path, filepath);
            if ( pathExists(_path) ) {
                result = _path;
            }
        }
    });
 
    if (result) {
        result = filename ? path.join(result, filename) : result;
    }
 
    return result;
};
 
Object.keys(path).forEach(function(member) {
    exports[member] = path[member];
});