Skip to content

Commit bd16153

Browse files
author
Brian Muenzenmeyer
committed
Merge pull request #342 from pattern-lab/flexible-engine-loading
Load engines flexibly from either the current directory's node_modules
2 parents 8778a93 + 3aaf422 commit bd16153

File tree

1 file changed

+50
-35
lines changed

1 file changed

+50
-35
lines changed

core/lib/pattern_engines.js

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,23 @@
1313
var path = require('path');
1414
var diveSync = require('diveSync');
1515
var engineMatcher = /^patternengine-node-(.*)$/;
16-
var enginesDirectory = path.join(process.cwd(), 'node_modules');
16+
var enginesDirectories = [
17+
{
18+
displayName: 'the core',
19+
path: path.resolve(__dirname, '..', '..', 'node_modules')
20+
},
21+
{
22+
displayName: 'the edition or test directory',
23+
path: path.join(process.cwd(), 'node_modules')
24+
}
25+
];
1726
var PatternEngines; // the main export object
1827
var engineNameForExtension; // generated mapping of extension to engine name
1928

2029

2130
// free "private" functions, for internal setup only
2231

23-
// given a path: return the engine name is the path points to a valid engine
32+
// given a path: return the engine name if the path points to a valid engine
2433
// module directory, or false if it doesn't
2534
function isEngineModule(filePath) {
2635
var baseName = path.basename(filePath);
@@ -30,54 +39,64 @@ function isEngineModule(filePath) {
3039
return false;
3140
}
3241

33-
function getEngineModulePath(engineName) {
34-
return path.resolve(enginesDirectory, "patternengine-node-" + engineName);
35-
}
36-
37-
// go find the names of all found engines
38-
function findSupportedPatternEngineNames() {
39-
var foundPatternEngineNames = [];
42+
function findEngineModulesInDirectory(dir) {
43+
var foundEngines = [];
4044

41-
// iterate over module directory and build a list of available pattern engine
42-
// names
43-
diveSync(enginesDirectory, {
45+
diveSync(dir, {
4446
recursive: false,
4547
directories: true
4648
}, function (err, filePath) {
4749
if (err) { throw err; }
4850
var foundEngineName = isEngineModule(filePath);
4951
if (foundEngineName) {
50-
foundPatternEngineNames.push(foundEngineName);
52+
foundEngines.push({
53+
name: foundEngineName,
54+
modulePath: filePath
55+
});
5156
}
5257
});
5358

54-
return foundPatternEngineNames;
59+
return foundEngines;
5560
}
5661

57-
58-
// try to load all supported engines
62+
// Try to load engines! We scan for engines at each path specified above. This
63+
// function is kind of a big deal.
5964
function loadAllEngines(enginesObject) {
6065
console.log('\nLoading engines...');
6166

62-
enginesObject.supportedPatternEngineNames.forEach(function (engineName) {
63-
var notLoaded = false;
64-
65-
try {
66-
enginesObject[engineName] = require(getEngineModulePath(engineName));
67-
} catch (err) {
68-
// Handle errors loading each pattern engine. This will usually be
69-
// because the engine's renderer hasn't been installed by the end user
70-
// -- we don't include any of them (except mustache) by default as
71-
// depedencies in package.json.
72-
notLoaded = (err.code === 'MODULE_NOT_FOUND');
73-
} finally {
74-
console.log('-', engineName, 'engine:',
75-
notLoaded ? 'renderer not installed; engine disabled' : 'good to go');
76-
}
67+
enginesDirectories.forEach(function (engineDirectory) {
68+
var enginesInThisDir = findEngineModulesInDirectory(engineDirectory.path);
69+
console.log("...scanning for engines in", engineDirectory.displayName + "...");
70+
71+
// find all engine-named things in this directory and try to load them,
72+
// unless it's already been loaded.
73+
enginesInThisDir.forEach(function (engineDiscovery) {
74+
var errorMessage;
75+
var successMessage = "good to go";
76+
77+
try {
78+
// give it a try! load 'er up. But not if we already have, of course.
79+
if (enginesObject[engineDiscovery.name]) {
80+
throw new Error("already loaded, skipping.");
81+
}
82+
enginesObject[engineDiscovery.name] = require(engineDiscovery.modulePath);
83+
} catch (err) {
84+
errorMessage = err.message;
85+
} finally {
86+
// report on the status of the engine, one way or another!
87+
console.log('-', engineDiscovery.name, 'engine:', errorMessage ? errorMessage : successMessage);
88+
}
89+
});
7790
});
91+
92+
// Complain if for some reason we haven't loaded any engines.
93+
if (Object.keys(enginesObject).length === 0) {
94+
throw new Error('No engines loaded! Something is seriously wrong.');
95+
}
7896
console.log('...done loading engines.\n');
7997
}
8098

99+
81100
// produce a mapping between file extension and engine name for each of the
82101
// loaded engines
83102
function createFileExtensionToEngineNameMap(enginesObject) {
@@ -108,10 +127,6 @@ function createFileExtensionToEngineNameMap(enginesObject) {
108127
// methods and properites below should therefore be on its prototype.
109128

110129
PatternEngines = Object.create({
111-
// build the list of supported pattern engines based on what plugins we have
112-
// in the pattern_engines directory
113-
supportedPatternEngineNames: findSupportedPatternEngineNames(),
114-
115130
getEngineNameForPattern: function (pattern) {
116131
// avoid circular dependency by putting this in here. TODO: is this slow?
117132
var of = require('./object_factory');

0 commit comments

Comments
 (0)