-
Notifications
You must be signed in to change notification settings - Fork 9
/
engine.js
128 lines (108 loc) · 4.89 KB
/
engine.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
var argv = require('yargs').argv;
var Bluebird = require('bluebird');
var path = require('path');
// since old versions of node can't do Object.assign :(
var mergeObjects = require('./utils/mergeObjects');
var requiringModule = module.parent.parent;
module.exports = function(inputOptions) {
var defaultOptions = {
printOutputFrame: true,
printOutput: true,
printErrorOutput: true
};
var options = mergeObjects(defaultOptions, inputOptions || {});
function printOutput(returnValue) {
Bluebird.resolve(returnValue)
.then(function (output) {
if (options.printOutput) {
if (options.printOutputFrame) {
console.log('--------make-runnable-output--------');
}
console.log(output);
if (options.printOutputFrame) {
console.log('------------------------------------');
}
}
}).catch(printError);
}
function printError(error) {
if (options.printErrorOutput) {
if (options.printOutputFrame) {
console.log('--------make-runnable-error--------');
}
console.log(error);
if (options.printOutputFrame) {
console.log('------------------------------------');
}
}
}
// if the requiring file is being run directly from the command line
if (require.main === requiringModule) {
var targetPropertyFound = false;
function runFuncWithArgs(func, unnamedArgs) {
var namedArgs = Object.assign({},argv);
delete namedArgs._;
delete namedArgs.$0;
if (Object.keys(namedArgs).length > 0 && unnamedArgs.length > 0) {
console.error('You cannot specify both named and unnamed arguments to the function');
process.exit(1);
} else if (Object.keys(namedArgs).length > 0) {
//we have named arguments. Let's pass these as an object to the function
printOutput(func(namedArgs));
} else if (unnamedArgs.length > 0) {
//we have 1 or more unnamed arguments. let's pass those as individual args to function
printOutput(func.apply(null, unnamedArgs));
} else {
//no extra arguments given to pass to function. let's just run it
printOutput(func());
}
}
// if the module exports a function, then evidently no target property could be specified
// all the rest of the target properties must then be the unnamed arguments to the function
if (requiringModule.exports instanceof Function) {
targetPropertyFound = true;
runFuncWithArgs(requiringModule.exports, argv._.slice(0));
} else if (argv._.length > 0) {
// there must be at least one argument which specifies the target property to run/show
var targetProperty = argv._[0];
if (targetProperty in requiringModule.exports) {
targetPropertyFound = true;
// if the target is a function, we need to run it with any provided args
if (requiringModule.exports[targetProperty] instanceof Function) {
runFuncWithArgs(requiringModule.exports[targetProperty].bind(requiringModule.exports), argv._.slice(1));
} else {// if the target isn't a function, we simply print it
printOutput(requiringModule.exports[targetProperty]);
}
}
}
// the specified first arg didn't match up to any of the exported properties
if (!targetPropertyFound) {
var validProperties = Object.keys(requiringModule.exports);
if (validProperties.length === 0) {
printError("The module you're trying to make runnable doesn't export anything.");
} else { // let's give an example of how this should be used
var validFunctionProperties = validProperties.filter(function(prop) {
return requiringModule.exports[prop] instanceof Function
});
// ideally the examples should use a function so it makes sense
var egProperty = validFunctionProperties.length > 0 ? validFunctionProperties[0] : validProperties[0];
// the example changes based on whether the property name contains a space
var egPropertyHasSpace = egProperty.indexOf(' ') > 0; //if example property
var egPropertyAsArg = egPropertyHasSpace ? '"' + egProperty + '"' : egProperty;
var example = 'node ' + argv.$0 + ' ' + egPropertyAsArg + ' xyz';
example += ' → ';
example += 'module.exports' + (egPropertyHasSpace ? '[' + egPropertyAsArg + ']': '.' + egProperty) + '("xyz")'
var errorString = 'One of the following must be specified as an argument, to run/print the corresponding function/property:';
errorString += '\n\n' + Object.keys(requiringModule.exports);
errorString += '\n\nExample:';
errorString += '\n\t' + example;
printError(errorString);
}
}
} else {
// needed with nested make-runnables
delete require.cache[path.join(__dirname, 'engine.js')]
delete require.cache[path.join(__dirname, 'index.js')]
delete require.cache[path.join(__dirname, 'custom.js')]
}
}