fix various path-related issues on Windows

- add env.pwd global, and use it instead of process.env.PWD, which is
undefined in Node.js on Windows
- normalize paths where necessary
This commit is contained in:
Jeff Williams 2013-11-10 16:57:48 -08:00
parent a21948c068
commit e0df71b1ae
11 changed files with 65 additions and 52 deletions

View File

@ -47,6 +47,15 @@ global.env = {
*/
dirname: '.',
/**
* The user's working directory at the time that JSDoc was started.
*
* @private
* @type string
* @memberof env
*/
pwd: null,
/**
* The command-line options, parsed into a key/value hash.
*
@ -76,7 +85,7 @@ global.env = {
(function(args) {
if (args[0] && typeof args[0] === 'object') {
// we should be on Node.js
args = [__dirname];
args = [__dirname, process.cwd()];
}
require('jsdoc/util/runtime').initialize(args);
@ -133,7 +142,7 @@ global.dump = function() {
cli.runCommand(cb);
}
catch(e) {
if (e.rhinoException !== null || e.rhinoException !== undefined) {
if (e.rhinoException) {
e.rhinoException.printStackTrace();
process.exit(1);
} else {

View File

@ -119,7 +119,7 @@ exports.getResourcePath = function(filepath, filename) {
// first, try resolving it relative to the working directory (or just normalize it if it's an
// absolute path)
result = path.resolve(process.env.PWD, filepath);
result = path.resolve(env.pwd, filepath);
if ( !pathExists(result) ) {
// next, try resolving it relative to the JSDoc directory
result = path.resolve(env.dirname, filepath);

View File

@ -1,3 +1,4 @@
/*global env: true */
/**
@module jsdoc/src/filter
@ -7,7 +8,7 @@
var path = require('jsdoc/path');
var pwd = process.env.PWD;
var pwd = env.pwd;
/**
@constructor

View File

@ -1,3 +1,4 @@
/*global env: true */
/**
@module jsdoc/src/scanner
@requires module:fs
@ -27,7 +28,7 @@ exports.Scanner.prototype.scan = function(searchPaths, depth, filter) {
var isFile;
var filePaths = [];
var pwd = process.env.PWD;
var pwd = env.pwd;
var self = this;
searchPaths = searchPaths || [];

View File

@ -14,26 +14,6 @@ var RHINO = exports.RHINO = 'rhino';
/** @private */
var NODE = exports.NODE = 'node';
// hacky conversion from Windows path to URI
function pathToUri(filepath) {
var uri = filepath;
// get drive
var drive = uri.match(/^[A-Za-z]/)[0] || '';
// strip drive/colon (if present; UNC paths won't have either)
uri = uri.replace(/^:?([A-Za-z]\:)?/, '');
// replace spaces with %20
uri = uri.replace(/\s/g, '%20');
// prepend drive (if present)
if (drive) {
uri = drive + ':' + uri;
}
// prepend URI scheme
uri = 'file:/' + uri;
return uri;
}
/**
* The JavaScript runtime that is executing JSDoc:
*
@ -94,6 +74,7 @@ function initializeRhino(args) {
}
env.dirname = getDirname();
env.pwd = String( java.lang.System.getenv().get('PWD') );
env.args = args;
require(env.dirname + '/rhino/rhino-shim.js');
@ -104,13 +85,15 @@ function initializeNode(args) {
var path = require('path');
var jsdocPath = args[0];
var pwd = process.env.PWD || args[1];
// resolve the path if it's a symlink
if ( fs.statSync(jsdocPath).isSymbolicLink() ) {
jsdocPath = fs.readlinkSync(jsdocPath);
jsdocPath = path.resolve( path.dirname(jsdocPath), fs.readlinkSync(jsdocPath) );
}
env.dirname = jsdocPath;
env.pwd = pwd;
env.args = process.argv.slice(2);
}
@ -145,10 +128,7 @@ exports.getRuntime = function() {
* @return {object} The require path for the runtime-specific implementation of the module.
*/
exports.getModulePath = function(partialPath) {
var modulePath = [env.dirname, runtime, partialPath].join('/').replace(/ /g, '%20');
if (os.platform() === 'win32') {
modulePath = pathToUri(modulePath);
}
return modulePath;
var path = require('path');
return path.join(env.dirname, runtime, partialPath);
};

View File

@ -1,4 +1,4 @@
/*global Packages: true */
/*global env: true, Packages: true */
/**
* Partial Rhino shim for Node.js' `fs` module.
@ -80,7 +80,7 @@ exports.readdir = asyncify(readdirSync);
// JSDoc extension to `fs` module
var toDir = exports.toDir = function(_path) {
var f = new java.io.File( path.resolve(process.env.PWD, _path) );
var f = new java.io.File( path.resolve(env.pwd, _path) );
if (f.isDirectory()){
return _path;
@ -101,7 +101,7 @@ exports.mkPath = function(_path) {
_path = _path.join('');
}
( new java.io.File(path.resolve(process.env.PWD, _path)) ).mkdirs();
( new java.io.File(path.resolve(env.pwd, _path)) ).mkdirs();
};
// JSDoc extension to `fs` module

View File

@ -1,6 +1,7 @@
/*global afterEach: true, beforeEach: true, describe: true, env: true, expect: true, it: true,
jasmine: true */
describe("module names", function() {
var path = require('jsdoc/path');
var runtime = require('jsdoc/util/runtime');
var doclets;
@ -9,7 +10,7 @@ describe("module names", function() {
var sourcePaths = env.opts._.slice(0);
beforeEach(function() {
env.opts._ = [env.dirname + '/test/fixtures/modules/data/'];
env.opts._ = [path.normalize(env.dirname + '/test/fixtures/modules/data/')];
srcParser = jasmine.createParser();
require('jsdoc/src/handlers').attachTo(srcParser);
});
@ -19,13 +20,17 @@ describe("module names", function() {
});
it("should create a name from the file path when no documented module name exists", function() {
doclets = srcParser.parse(env.dirname + '/test/fixtures/modules/data/mod-1.js');
doclets = srcParser.parse(
path.normalize(env.dirname + '/test/fixtures/modules/data/mod-1.js')
);
expect(doclets.length).toBeGreaterThan(1);
expect(doclets[0].longname).toEqual('module:data/mod-1');
});
it("should use the documented module name if available", function() {
doclets = srcParser.parse(env.dirname + '/test/fixtures/modules/data/mod-2.js');
doclets = srcParser.parse(
path.normalize(env.dirname + '/test/fixtures/modules/data/mod-2.js')
);
expect(doclets.length).toBeGreaterThan(1);
expect(doclets[0].longname).toEqual('module:my/module/name');
});

View File

@ -1,12 +1,20 @@
/*global describe: true, expect: true, it: true */
describe("jsdoc/src/filter", function() {
var path = require('jsdoc/path');
var filter = new (require('jsdoc/src/filter').Filter)({
includePattern: new RegExp(".+\\.js(doc)?$"),
excludePattern: new RegExp("(^|\\/|\\\\)_"),
exclude: ['.ignore', 'scratch/conf.js']
});
var files = ['yes.js', '/yes.jsdoc', '/_nope.js', '.ignore', process.env.PWD + '/scratch/conf.js'];
var files = [
'yes.js',
'/yes.jsdoc',
'/_nope.js',
'.ignore',
path.normalize(env.pwd + '/scratch/conf.js')
];
files = files.filter(function($) {
return filter.isIncluded($);

View File

@ -1,15 +1,17 @@
/*global describe: true, env: true, expect: true, it: true */
describe("jsdoc/src/scanner", function() {
var scanner = new (require('jsdoc/src/scanner').Scanner)(),
filter = new (require('jsdoc/src/filter').Filter)({
includePattern: new RegExp(".+\\.js(doc)?$"),
excludePattern: new RegExp("(^|\\/|\\\\)_")
}),
path = require('path'),
sourceFiles = scanner.scan([path.join(process.env.PWD, 'test', 'fixtures', 'src')], 3, filter);
var path = require('path');
var filter = new (require('jsdoc/src/filter').Filter)({
includePattern: new RegExp(".+\\.js(doc)?$"),
excludePattern: new RegExp("(^|\\/|\\\\)_")
});
var scanner = new (require('jsdoc/src/scanner').Scanner)();
var sourcePath = path.normalize(env.pwd + '/test/fixtures/src');
var sourceFiles = scanner.scan([sourcePath], 3, filter);
sourceFiles = sourceFiles.map(function($) {
return path.relative(process.env.PWD, $);
return path.relative(env.pwd, $);
});
it("should return the correct source files", function() {

View File

@ -2,15 +2,21 @@
jasmine: true */
// TODO: consolidate with specs/jsdoc/parser and specs/jsdoc/plugins
describe("plugins", function() {
var path = require('jsdoc/path');
var docSet;
var pluginPaths = [
path.normalize(env.dirname + '/test/fixtures/testPlugin1'),
path.normalize(env.dirname + '/test/fixtures/testPlugin2')
];
// TODO: decouple this from the global parser
app.jsdoc.parser = jasmine.createParser();
global.jsdocPluginsTest = global.jsdocPluginsTest || {};
require('jsdoc/plugins').installPlugins(['test/fixtures/testPlugin1',
'test/fixtures/testPlugin2'], app.jsdoc.parser);
require('jsdoc/plugins').installPlugins(pluginPaths, app.jsdoc.parser);
docSet = jasmine.getDocSetFromFile('test/fixtures/plugins.js', app.jsdoc.parser);

View File

@ -2,6 +2,7 @@
jasmine: true */
describe("@overview tag", function() {
var path = require('jsdoc/path');
var runtime = require('jsdoc/util/runtime');
var doclets;
@ -10,7 +11,7 @@ describe("@overview tag", function() {
var sourcePaths = env.opts._.slice(0);
beforeEach(function() {
env.opts._ = [env.dirname + '/test/fixtures/'];
env.opts._ = [path.normalize(env.dirname + '/test/fixtures/')];
srcParser = jasmine.createParser();
require('jsdoc/src/handlers').attachTo(srcParser);
});
@ -20,12 +21,12 @@ describe("@overview tag", function() {
});
it('When a file overview tag appears in a doclet, the name of the doclet should contain the path to the file.', function() {
doclets = srcParser.parse(env.dirname + '/test/fixtures/file.js');
doclets = srcParser.parse( path.normalize(env.dirname + '/test/fixtures/file.js') );
expect(doclets[0].name).toMatch(/^(fixtures[\/\\]file\.js)$/);
});
it("The name and longname should be equal", function() {
doclets = srcParser.parse(env.dirname + '/test/fixtures/file.js');
doclets = srcParser.parse( path.normalize(env.dirname + '/test/fixtures/file.js') );
expect(doclets[0].name).toBe(doclets[0].longname);
});
});