Skip to content

Commit

Permalink
fix various path-related issues on Windows
Browse files Browse the repository at this point in the history
- add env.pwd global, and use it instead of process.env.PWD, which is
undefined in Node.js on Windows
- normalize paths where necessary
  • Loading branch information
hegemonic committed Nov 11, 2013
1 parent a21948c commit e0df71b
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 52 deletions.
13 changes: 11 additions & 2 deletions jsdoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion lib/jsdoc/path.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion lib/jsdoc/src/filter.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/*global env: true */
/**
@module jsdoc/src/filter
Expand All @@ -7,7 +8,7 @@

var path = require('jsdoc/path');

var pwd = process.env.PWD;
var pwd = env.pwd;

/**
@constructor
Expand Down
3 changes: 2 additions & 1 deletion lib/jsdoc/src/scanner.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/*global env: true */
/**
@module jsdoc/src/scanner
@requires module:fs
Expand Down Expand Up @@ -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 || [];
Expand Down
34 changes: 7 additions & 27 deletions lib/jsdoc/util/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -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:
*
Expand Down Expand Up @@ -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');
Expand All @@ -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);
}

Expand Down Expand Up @@ -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);
};
6 changes: 3 additions & 3 deletions rhino/fs.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*global Packages: true */
/*global env: true, Packages: true */

/**
* Partial Rhino shim for Node.js' `fs` module.
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down
11 changes: 8 additions & 3 deletions test/specs/documentation/modules.js
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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);
});
Expand All @@ -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');
});
Expand Down
10 changes: 9 additions & 1 deletion test/specs/jsdoc/src/filter.js
Original file line number Diff line number Diff line change
@@ -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($);
Expand Down
18 changes: 10 additions & 8 deletions test/specs/jsdoc/src/scanner.js
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down
10 changes: 8 additions & 2 deletions test/specs/plugins/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
7 changes: 4 additions & 3 deletions test/specs/tags/overviewtag.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
jasmine: true */

describe("@overview tag", function() {
var path = require('jsdoc/path');
var runtime = require('jsdoc/util/runtime');

var doclets;
Expand All @@ -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);
});
Expand All @@ -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);
});
});

0 comments on commit e0df71b

Please sign in to comment.