Skip to content

Commit 4a1c1b7

Browse files
committed
Provide more helpful errors when trying to require non-existent modules
1 parent 9eb9511 commit 4a1c1b7

4 files changed

Lines changed: 130 additions & 114 deletions

File tree

src/main/js/lib/find.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict';
2+
var File = java.io.File;
3+
module.exports = function find(dir, filter) {
4+
var result = [];
5+
function recurse( dir, store ) {
6+
var files,
7+
len,
8+
i,
9+
file,
10+
dirfile = new File( dir );
11+
12+
if ( typeof filter == 'undefined' ) {
13+
files = dirfile.list();
14+
} else {
15+
files = dirfile.list(filter);
16+
}
17+
len = files.length; i = 0;
18+
for (; i < len; i++){
19+
file = new File( dir + '/' + files[i] );
20+
if ( file.isDirectory() ) {
21+
recurse( file.canonicalPath, store );
22+
} else {
23+
store.push( ('' + file.canonicalPath).replace(/\\\\/g,'/') );
24+
}
25+
}
26+
}
27+
recurse( dir, result );
28+
return result;
29+
};

src/main/js/lib/plugin.js

Lines changed: 33 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
'use strict';
22
/*global persist,exports,config,__plugin,require*/
33
var File = java.io.File,
4-
FileWriter = java.io.FileWriter,
5-
PrintWriter = java.io.PrintWriter;
4+
FileWriter = java.io.FileWriter,
5+
PrintWriter = java.io.PrintWriter,
6+
find = require('./find');
67
/*
78
plugin management
89
*/
910
var _plugins = {};
1011

11-
var _plugin = function(/* String */ moduleName, /* Object */ moduleObject, isPersistent ) {
12+
function _plugin(/* String */ moduleName, /* Object */ moduleObject, isPersistent ) {
1213
//
1314
// don't load plugin more than once
1415
//
@@ -26,67 +27,46 @@ var _plugin = function(/* String */ moduleName, /* Object */ moduleObject, isPer
2627
moduleObject.store = persist( moduleName, moduleObject.store );
2728
}
2829
return moduleObject;
29-
};
30+
}
3031

31-
exports.plugin = _plugin;
32-
33-
exports.autoload = function( context, pluginDir, options ) {
34-
var _canonize = function( file ) {
35-
return '' + file.canonicalPath.replaceAll('\\\\','/');
36-
};
37-
/*
38-
recursively walk the given directory and return a list of all .js files
39-
*/
40-
var _listSourceFiles = function( store, dir ) {
41-
var files = dir.listFiles(),
42-
file;
43-
if ( !files ) {
44-
return;
45-
}
46-
for ( var i = 0; i < files.length; i++ ) {
47-
file = files[i];
48-
if ( file.isDirectory( ) ) {
49-
_listSourceFiles( store, file );
50-
}else{
51-
if ( file.canonicalPath.endsWith( '.js' ) ) {
52-
store.push( file );
53-
}
54-
}
55-
}
56-
};
32+
function _autoload( context, pluginDir, options ) {
5733
/*
5834
Reload all of the .js files in the given directory
5935
*/
60-
(function( pluginDir ) {
61-
var sourceFiles = [],
36+
var sourceFiles = [],
6237
property,
6338
module,
6439
pluginPath;
65-
_listSourceFiles( sourceFiles, pluginDir );
40+
sourceFiles = find(pluginDir);
6641

67-
var len = sourceFiles.length;
68-
if ( config && config.verbose ) {
69-
console.info( len + ' scriptcraft plugins found in ' + pluginDir );
70-
}
42+
var len = sourceFiles.length;
43+
if ( config && config.verbose ) {
44+
console.info( len + ' scriptcraft plugins found in ' + pluginDir );
45+
}
7146

72-
for ( var i = 0; i < len; i++ ) {
47+
for ( var i = 0; i < len; i++ ) {
7348

74-
pluginPath = _canonize( sourceFiles[i] );
75-
module = {};
49+
pluginPath = sourceFiles[i];
50+
if (!pluginPath.match(/\.js$/)){
51+
continue;
52+
}
53+
module = {};
7654

77-
try {
78-
module = require( pluginPath , options);
79-
for ( property in module ) {
80-
/*
81-
all exports in plugins become members of context object
82-
*/
83-
context[property] = module[property];
84-
}
85-
} catch ( e ) {
86-
var msg = 'Plugin ' + pluginPath + ' ' + e ;
87-
console.error( msg );
55+
try {
56+
module = require( pluginPath , options);
57+
for ( property in module ) {
58+
/*
59+
all exports in plugins become members of context object
60+
*/
61+
context[property] = module[property];
8862
}
63+
} catch ( e ) {
64+
var msg = 'Plugin ' + pluginPath + ' ' + e ;
65+
console.error( msg );
8966
}
90-
}(pluginDir));
91-
};
67+
}
68+
69+
}
70+
exports.plugin = _plugin;
71+
exports.autoload = _autoload;
9272

src/main/js/lib/require.js

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,20 @@ module specification, the '.js' suffix is optional.
6565
var File = java.io.File,
6666
FileReader = java.io.FileReader,
6767
BufferedReader = java.io.BufferedReader;
68+
69+
function fileExists( file ) {
70+
if ( file.isDirectory() ) {
71+
return readModuleFromDirectory( file );
72+
} else {
73+
return file;
74+
}
75+
}
76+
77+
function _canonize(file){
78+
return "" + file.canonicalPath.replaceAll("\\\\","/");
79+
}
6880

69-
var readModuleFromDirectory = function( dir ) {
81+
function readModuleFromDirectory( dir ) {
7082

7183
// look for a package.json file
7284
var pkgJsonFile = new File( dir, './package.json' );
@@ -87,19 +99,8 @@ module specification, the '.js' suffix is optional.
8799
return null;
88100
}
89101
}
90-
};
91-
92-
var fileExists = function( file ) {
93-
if ( file.isDirectory() ) {
94-
return readModuleFromDirectory( file );
95-
} else {
96-
return file;
97-
}
98-
};
102+
}
99103

100-
var _canonize = function(file){
101-
return "" + file.canonicalPath.replaceAll("\\\\","/");
102-
};
103104

104105
/**********************************************************************
105106
### module name resolution
@@ -135,7 +136,7 @@ When resolving module names to file paths, ScriptCraft uses the following rules.
135136
3.2 if no package.json file exists then look for an index.js file in the directory
136137
137138
***/
138-
var resolveModuleToFile = function ( moduleName, parentDir ) {
139+
function resolveModuleToFile( moduleName, parentDir ) {
139140
var file = new File(moduleName),
140141
i = 0,
141142
pathWithJSExt,
@@ -179,13 +180,11 @@ When resolving module names to file paths, ScriptCraft uses the following rules.
179180
}
180181
}
181182
return null;
182-
};
183-
var _loadedModules = {};
184-
var _format = java.lang.String.format;
183+
}
185184
/*
186185
require() function implementation
187186
*/
188-
var _require = function( parentFile, path, options ) {
187+
function _require( parentFile, path, options ) {
189188
var file,
190189
canonizedFilename,
191190
moduleInfo,
@@ -209,6 +208,29 @@ When resolving module names to file paths, ScriptCraft uses the following rules.
209208
if (! ( (''+path).match( /^\./ ) ) ) {
210209
errMsg = errMsg + ' and not found in paths ' + JSON.stringify(modulePaths);
211210
}
211+
var find = _require(parentFile, 'find').exports;
212+
var allJS = [];
213+
for (var i = 0;i < modulePaths.length; i++){
214+
var js = find( modulePaths[i] );
215+
for (var j = 0;j < js.length; j++){
216+
if (js[j].match(/\.js$/)){
217+
allJS.push( js[j].replace(modulePaths[i],'') );
218+
}
219+
}
220+
}
221+
var pathL = path.toLowerCase();
222+
var candidates = [];
223+
for (i = 0;i < allJS.length;i++){
224+
var filenameparts = allJS[i];
225+
var candidate = filenameparts.replace(/\.js/,'') ;
226+
var lastpart = candidate.toLowerCase();
227+
if (pathL.indexOf(lastpart) > -1 || lastpart.indexOf(pathL) > -1){
228+
candidates.push(candidate);
229+
}
230+
}
231+
if (candidates.length > 0){
232+
errMsg += '\nBut found module/s named: ' + candidates.join(',') + ' - is this what you meant?';
233+
}
212234
throw new Error(errMsg);
213235
}
214236
canonizedFilename = _canonize(file);
@@ -285,14 +307,16 @@ When resolving module names to file paths, ScriptCraft uses the following rules.
285307
}
286308
moduleInfo.loaded = true;
287309
return moduleInfo;
288-
};
310+
}
289311

290-
var _requireClosure = function( parent ) {
291-
return function( path, options ) {
312+
function _requireClosure( parent ) {
313+
return function requireBoundToParent( path, options ) {
292314
var module = _require( parent, path , options);
293315
return module.exports;
294316
};
295-
};
317+
}
318+
var _loadedModules = {};
319+
var _format = java.lang.String.format;
296320
return _requireClosure( new java.io.File(rootDir) );
297321
// last line deliberately has no semicolon!
298322
})

0 commit comments

Comments
 (0)