Provide more helpful errors when trying to require non-existent modules
This commit is contained in:
parent
9eb95113c2
commit
4a1c1b7b01
4 changed files with 131 additions and 115 deletions
29
src/main/js/lib/find.js
Normal file
29
src/main/js/lib/find.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
'use strict';
|
||||
var File = java.io.File;
|
||||
module.exports = function find(dir, filter) {
|
||||
var result = [];
|
||||
function recurse( dir, store ) {
|
||||
var files,
|
||||
len,
|
||||
i,
|
||||
file,
|
||||
dirfile = new File( dir );
|
||||
|
||||
if ( typeof filter == 'undefined' ) {
|
||||
files = dirfile.list();
|
||||
} else {
|
||||
files = dirfile.list(filter);
|
||||
}
|
||||
len = files.length; i = 0;
|
||||
for (; i < len; i++){
|
||||
file = new File( dir + '/' + files[i] );
|
||||
if ( file.isDirectory() ) {
|
||||
recurse( file.canonicalPath, store );
|
||||
} else {
|
||||
store.push( ('' + file.canonicalPath).replace(/\\\\/g,'/') );
|
||||
}
|
||||
}
|
||||
}
|
||||
recurse( dir, result );
|
||||
return result;
|
||||
};
|
|
@ -1,14 +1,15 @@
|
|||
'use strict';
|
||||
/*global persist,exports,config,__plugin,require*/
|
||||
var File = java.io.File,
|
||||
FileWriter = java.io.FileWriter,
|
||||
PrintWriter = java.io.PrintWriter;
|
||||
FileWriter = java.io.FileWriter,
|
||||
PrintWriter = java.io.PrintWriter,
|
||||
find = require('./find');
|
||||
/*
|
||||
plugin management
|
||||
*/
|
||||
var _plugins = {};
|
||||
|
||||
var _plugin = function(/* String */ moduleName, /* Object */ moduleObject, isPersistent ) {
|
||||
function _plugin(/* String */ moduleName, /* Object */ moduleObject, isPersistent ) {
|
||||
//
|
||||
// don't load plugin more than once
|
||||
//
|
||||
|
@ -26,67 +27,46 @@ var _plugin = function(/* String */ moduleName, /* Object */ moduleObject, isPer
|
|||
moduleObject.store = persist( moduleName, moduleObject.store );
|
||||
}
|
||||
return moduleObject;
|
||||
};
|
||||
}
|
||||
|
||||
exports.plugin = _plugin;
|
||||
|
||||
exports.autoload = function( context, pluginDir, options ) {
|
||||
var _canonize = function( file ) {
|
||||
return '' + file.canonicalPath.replaceAll('\\\\','/');
|
||||
};
|
||||
/*
|
||||
recursively walk the given directory and return a list of all .js files
|
||||
*/
|
||||
var _listSourceFiles = function( store, dir ) {
|
||||
var files = dir.listFiles(),
|
||||
file;
|
||||
if ( !files ) {
|
||||
return;
|
||||
}
|
||||
for ( var i = 0; i < files.length; i++ ) {
|
||||
file = files[i];
|
||||
if ( file.isDirectory( ) ) {
|
||||
_listSourceFiles( store, file );
|
||||
}else{
|
||||
if ( file.canonicalPath.endsWith( '.js' ) ) {
|
||||
store.push( file );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
function _autoload( context, pluginDir, options ) {
|
||||
/*
|
||||
Reload all of the .js files in the given directory
|
||||
*/
|
||||
(function( pluginDir ) {
|
||||
var sourceFiles = [],
|
||||
var sourceFiles = [],
|
||||
property,
|
||||
module,
|
||||
pluginPath;
|
||||
_listSourceFiles( sourceFiles, pluginDir );
|
||||
sourceFiles = find(pluginDir);
|
||||
|
||||
var len = sourceFiles.length;
|
||||
if ( config && config.verbose ) {
|
||||
console.info( len + ' scriptcraft plugins found in ' + pluginDir );
|
||||
var len = sourceFiles.length;
|
||||
if ( config && config.verbose ) {
|
||||
console.info( len + ' scriptcraft plugins found in ' + pluginDir );
|
||||
}
|
||||
|
||||
for ( var i = 0; i < len; i++ ) {
|
||||
|
||||
pluginPath = sourceFiles[i];
|
||||
if (!pluginPath.match(/\.js$/)){
|
||||
continue;
|
||||
}
|
||||
module = {};
|
||||
|
||||
for ( var i = 0; i < len; i++ ) {
|
||||
|
||||
pluginPath = _canonize( sourceFiles[i] );
|
||||
module = {};
|
||||
|
||||
try {
|
||||
module = require( pluginPath , options);
|
||||
for ( property in module ) {
|
||||
/*
|
||||
all exports in plugins become members of context object
|
||||
*/
|
||||
context[property] = module[property];
|
||||
}
|
||||
} catch ( e ) {
|
||||
var msg = 'Plugin ' + pluginPath + ' ' + e ;
|
||||
console.error( msg );
|
||||
try {
|
||||
module = require( pluginPath , options);
|
||||
for ( property in module ) {
|
||||
/*
|
||||
all exports in plugins become members of context object
|
||||
*/
|
||||
context[property] = module[property];
|
||||
}
|
||||
} catch ( e ) {
|
||||
var msg = 'Plugin ' + pluginPath + ' ' + e ;
|
||||
console.error( msg );
|
||||
}
|
||||
}(pluginDir));
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
exports.plugin = _plugin;
|
||||
exports.autoload = _autoload;
|
||||
|
||||
|
|
|
@ -65,8 +65,20 @@ module specification, the '.js' suffix is optional.
|
|||
var File = java.io.File,
|
||||
FileReader = java.io.FileReader,
|
||||
BufferedReader = java.io.BufferedReader;
|
||||
|
||||
function fileExists( file ) {
|
||||
if ( file.isDirectory() ) {
|
||||
return readModuleFromDirectory( file );
|
||||
} else {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
function _canonize(file){
|
||||
return "" + file.canonicalPath.replaceAll("\\\\","/");
|
||||
}
|
||||
|
||||
var readModuleFromDirectory = function( dir ) {
|
||||
function readModuleFromDirectory( dir ) {
|
||||
|
||||
// look for a package.json file
|
||||
var pkgJsonFile = new File( dir, './package.json' );
|
||||
|
@ -87,19 +99,8 @@ module specification, the '.js' suffix is optional.
|
|||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var fileExists = function( file ) {
|
||||
if ( file.isDirectory() ) {
|
||||
return readModuleFromDirectory( file );
|
||||
} else {
|
||||
return file;
|
||||
}
|
||||
};
|
||||
|
||||
var _canonize = function(file){
|
||||
return "" + file.canonicalPath.replaceAll("\\\\","/");
|
||||
};
|
||||
|
||||
/**********************************************************************
|
||||
### module name resolution
|
||||
|
@ -135,7 +136,7 @@ When resolving module names to file paths, ScriptCraft uses the following rules.
|
|||
3.2 if no package.json file exists then look for an index.js file in the directory
|
||||
|
||||
***/
|
||||
var resolveModuleToFile = function ( moduleName, parentDir ) {
|
||||
function resolveModuleToFile( moduleName, parentDir ) {
|
||||
var file = new File(moduleName),
|
||||
i = 0,
|
||||
pathWithJSExt,
|
||||
|
@ -179,13 +180,11 @@ When resolving module names to file paths, ScriptCraft uses the following rules.
|
|||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
var _loadedModules = {};
|
||||
var _format = java.lang.String.format;
|
||||
}
|
||||
/*
|
||||
require() function implementation
|
||||
*/
|
||||
var _require = function( parentFile, path, options ) {
|
||||
function _require( parentFile, path, options ) {
|
||||
var file,
|
||||
canonizedFilename,
|
||||
moduleInfo,
|
||||
|
@ -209,6 +208,29 @@ When resolving module names to file paths, ScriptCraft uses the following rules.
|
|||
if (! ( (''+path).match( /^\./ ) ) ) {
|
||||
errMsg = errMsg + ' and not found in paths ' + JSON.stringify(modulePaths);
|
||||
}
|
||||
var find = _require(parentFile, 'find').exports;
|
||||
var allJS = [];
|
||||
for (var i = 0;i < modulePaths.length; i++){
|
||||
var js = find( modulePaths[i] );
|
||||
for (var j = 0;j < js.length; j++){
|
||||
if (js[j].match(/\.js$/)){
|
||||
allJS.push( js[j].replace(modulePaths[i],'') );
|
||||
}
|
||||
}
|
||||
}
|
||||
var pathL = path.toLowerCase();
|
||||
var candidates = [];
|
||||
for (i = 0;i < allJS.length;i++){
|
||||
var filenameparts = allJS[i];
|
||||
var candidate = filenameparts.replace(/\.js/,'') ;
|
||||
var lastpart = candidate.toLowerCase();
|
||||
if (pathL.indexOf(lastpart) > -1 || lastpart.indexOf(pathL) > -1){
|
||||
candidates.push(candidate);
|
||||
}
|
||||
}
|
||||
if (candidates.length > 0){
|
||||
errMsg += '\nBut found module/s named: ' + candidates.join(',') + ' - is this what you meant?';
|
||||
}
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
canonizedFilename = _canonize(file);
|
||||
|
@ -285,14 +307,16 @@ When resolving module names to file paths, ScriptCraft uses the following rules.
|
|||
}
|
||||
moduleInfo.loaded = true;
|
||||
return moduleInfo;
|
||||
};
|
||||
}
|
||||
|
||||
var _requireClosure = function( parent ) {
|
||||
return function( path, options ) {
|
||||
function _requireClosure( parent ) {
|
||||
return function requireBoundToParent( path, options ) {
|
||||
var module = _require( parent, path , options);
|
||||
return module.exports;
|
||||
};
|
||||
};
|
||||
}
|
||||
var _loadedModules = {};
|
||||
var _format = java.lang.String.format;
|
||||
return _requireClosure( new java.io.File(rootDir) );
|
||||
// last line deliberately has no semicolon!
|
||||
})
|
||||
|
|
|
@ -143,7 +143,7 @@ This can be useful if you write a plugin that needs to store location data since
|
|||
A JSON object in the above form.
|
||||
|
||||
***/
|
||||
var _locationToJSON = function( location ) {
|
||||
function _locationToJSON( location ) {
|
||||
var yaw = __plugin.bukkit ? location.yaw : (__plugin.canary ? location.rotation : 0);
|
||||
return {
|
||||
world: ''+location.world.name,
|
||||
|
@ -175,7 +175,7 @@ lookupTable[key] = player.name;
|
|||
```
|
||||
|
||||
***/
|
||||
exports.locationToString = function( location ) {
|
||||
exports.locationToString = function locationToString( location ) {
|
||||
return JSON.stringify( _locationToJSON( location ) );
|
||||
};
|
||||
exports.locationToJSON = _locationToJSON;
|
||||
|
@ -190,7 +190,7 @@ returned by locationToJSON() and reconstructs and returns a bukkit
|
|||
Location object.
|
||||
|
||||
***/
|
||||
exports.locationFromJSON = function( json ) {
|
||||
exports.locationFromJSON = function locationFromJSON( json ) {
|
||||
var world;
|
||||
if ( json.constructor == Array ) {
|
||||
// for support of legacy format
|
||||
|
@ -210,7 +210,7 @@ exports.locationFromJSON = function( json ) {
|
|||
|
||||
exports.player = _player;
|
||||
|
||||
exports.getPlayerObject = function( player ) {
|
||||
exports.getPlayerObject = function getPlayerObject( player ) {
|
||||
console.warn( 'utils.getPlayerObject() is deprecated. Use utils.player() instead.' );
|
||||
return _player(player);
|
||||
};
|
||||
|
@ -281,7 +281,7 @@ if (targetPos){
|
|||
```
|
||||
|
||||
***/
|
||||
exports.getMousePos = function( player ) {
|
||||
exports.getMousePos = function getMousePos( player ) {
|
||||
|
||||
player = _player(player);
|
||||
if ( !player ) {
|
||||
|
@ -366,20 +366,20 @@ utils.foreach (players, function( player ) {
|
|||
Java-style collection. This is important because many objects in the
|
||||
CanaryMod and Bukkit APIs use Java-style collections.
|
||||
***/
|
||||
var _foreach = function( array, callback, context, delay, onCompletion ) {
|
||||
function _foreach( array, callback, context, delay, onCompletion ) {
|
||||
if ( array instanceof java.util.Collection ) {
|
||||
array = array.toArray();
|
||||
}
|
||||
var i = 0;
|
||||
var len = array.length;
|
||||
function next() {
|
||||
callback(array[i], i, context, array);
|
||||
i++;
|
||||
}
|
||||
function hasNext() {
|
||||
return i < len;
|
||||
}
|
||||
if ( delay ) {
|
||||
var next = function( ) {
|
||||
callback(array[i], i, context, array);
|
||||
i++;
|
||||
};
|
||||
var hasNext = function( ) {
|
||||
return i < len;
|
||||
};
|
||||
_nicely( next, hasNext, onCompletion, delay );
|
||||
} else {
|
||||
for ( ;i < len; i++ ) {
|
||||
|
@ -412,7 +412,7 @@ function and the start of the next `next()` function.
|
|||
See the source code to utils.foreach for an example of how utils.nicely is used.
|
||||
|
||||
***/
|
||||
var _nicely = function( next, hasNext, onDone, delay ) {
|
||||
function _nicely( next, hasNext, onDone, delay ) {
|
||||
if ( hasNext() ){
|
||||
next();
|
||||
setTimeout( function() {
|
||||
|
@ -426,11 +426,12 @@ var _nicely = function( next, hasNext, onDone, delay ) {
|
|||
};
|
||||
exports.nicely = _nicely;
|
||||
|
||||
exports.at = function( time24hr, callback, pWorlds, repeat ) {
|
||||
function _at( time24hr, callback, pWorlds, repeat ) {
|
||||
console.warn("utils.at() is deprecated, use require('at') instead");
|
||||
var at = require('at');
|
||||
return at( time24hr, callback, pWorlds, repeat);
|
||||
};
|
||||
}
|
||||
exports.at = _at;
|
||||
/*************************************************************************
|
||||
### utils.time( world ) function
|
||||
|
||||
|
@ -501,27 +502,9 @@ var jsFiles = utils.find('./', function(dir,name){
|
|||
});
|
||||
```
|
||||
***/
|
||||
exports.find = function( dir , filter ) {
|
||||
var result = [];
|
||||
var recurse = function( dir, store ) {
|
||||
var files, dirfile = new File( dir );
|
||||
|
||||
if ( typeof filter == 'undefined' ) {
|
||||
files = dirfile.list();
|
||||
} else {
|
||||
files = dirfile.list(filter);
|
||||
}
|
||||
_foreach( files, function( file ) {
|
||||
file = new File( dir + '/' + file );
|
||||
if ( file.isDirectory() ) {
|
||||
recurse( file.canonicalPath, store );
|
||||
} else {
|
||||
store.push( file.canonicalPath );
|
||||
}
|
||||
});
|
||||
};
|
||||
recurse( dir, result );
|
||||
return result;
|
||||
exports.find = function( path, filter){
|
||||
console.warn("utils.find() is deprecated, use require('find') instead");
|
||||
return require('find')(path, filter);
|
||||
};
|
||||
/************************************************************************
|
||||
### utils.serverAddress() function
|
||||
|
@ -534,7 +517,7 @@ var serverAddress = utils.serverAddress();
|
|||
console.log(serverAddress);
|
||||
```
|
||||
***/
|
||||
exports.serverAddress = function() {
|
||||
exports.serverAddress = function serverAddress() {
|
||||
var interfaces = java.net.NetworkInterface.getNetworkInterfaces();
|
||||
var current,
|
||||
addresses,
|
||||
|
@ -682,7 +665,7 @@ if (__plugin.canary){
|
|||
function getPlayerNames(){
|
||||
return getPlayers().map(function(p){ return p.name; });
|
||||
}
|
||||
exports.players = function(fn){
|
||||
exports.players = function players(fn){
|
||||
var result = getPlayers();
|
||||
if (fn){
|
||||
result.forEach(fn);
|
||||
|
|
Reference in a new issue