-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstrumenter_runner.js
More file actions
135 lines (105 loc) · 4.52 KB
/
instrumenter_runner.js
File metadata and controls
135 lines (105 loc) · 4.52 KB
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
129
130
131
132
133
134
135
/**
* @description Instruments all JS functions of a project with logging
* information. Relies on Esprima parser to detect all JS functions.
*
* The instrumentation functions can be found in the js_editor.js
* Currently it uses the instrumentation_log function which makes a
* request to the instrumentation_server; which will store all alive functions
* under _alive_functions.json
*
* @version 0.1
* @author Kishan Nirghin
* @Date 05-02-2019
*
* @param <sourceFolder>
*/
'use strict';
const fs = require("fs-extra"),
path = require("path"),
fileName = path.basename(__filename);
var helper = require("./helper");
var JsEditor = require("./js_editor"),
HTMLEditor = require("./html_editor");
require("./prototype_extension");
function run(options) {
if( ! options["source"] ) {
console.log(`usage: node ${fileName} <source>`);
process.exit(1);
}
options["file"] = (path.extname(options["source"]) != ""); // Boolean: source==file.
var sourceFolder = path.dirname(options["source"]);
// exception to get the source folder (dirname gives the parent folder when source is a folder)
if (!options["file"]) {
sourceFolder = "./" + path.join(sourceFolder, path.basename(options["source"]));
}
var instrumentedSourceFolder = sourceFolder + "_instrumented";
if (options["destination"]) {
instrumentedSourceFolder = options["destination"];
}
var instrumentedSourceFile = null;
if (options["file"]) {
instrumentedSourceFile = "./" + path.join(instrumentedSourceFolder, path.basename(options["source"]));
}
if (fs.existsSync(instrumentedSourceFolder)) {
console.log(`Warning folder ${instrumentedSourceFolder} already exists`);
if (!options["force"]) { process.exit(1); }
console.log(`(Force override activated, continuing..)`);
}
/* allow users to override the source folder */
if (path.dirname(sourceFolder) != path.dirname(instrumentedSourceFolder) ||
path.basename(sourceFolder) != path.basename(instrumentedSourceFolder)) {
fs.copySync(sourceFolder, instrumentedSourceFolder);
}
var allFunctions = []; // keep track of all functions that were instrumented
if (options["file"]) {
var htmle = new HTMLEditor().loadFile(instrumentedSourceFile);
var externalScripts = htmle.getExternalScripts();
externalScripts.forEach((extScript) => {
var jse = new JsEditor().loadFile(extScript.src);
var functionsOfFile = jse.instrumentFunctions(options);
allFunctions = allFunctions.concat(functionsOfFile);
jse.saveFile();
});
var internalScripts = htmle.getInternalScripts();
internalScripts.forEach((intScript) => {
var jse = new JsEditor().loadSource(intScript.source, intScript.src);
var functionsOfFile = jse.instrumentFunctions(options);
allFunctions = allFunctions.concat(functionsOfFile);
htmle.updateInternalScript(jse.getOriginalSource(), jse.getSource());
htmle.saveFile();
});
} else {
/* retrieve all .js files within these folders */
var jsFilePaths = helper.getJsFilePaths(instrumentedSourceFolder);
/* instrument all functions in these .js files */
jsFilePaths.forEach((jsFilePath) => {
var jse = new JsEditor().loadFile(jsFilePath);
var functionsOfFile = jse.instrumentFunctions(options);
allFunctions = allFunctions.concat(functionsOfFile);
jse.saveFile();
});
// TODO: look for js functions inside HTML and other files
}
fixFilePaths(allFunctions, instrumentedSourceFolder); // removes unused part of pwd from filepaths
var resultLocation = path.join(instrumentedSourceFolder, "_all_functions.json");
fs.writeFileSync(resultLocation, JSON.stringify(allFunctions), 'utf8');
}
/**
* By default the filenames of the functions are relative to the pwd on execution
* Lets fix it so that it is relative to the project folder.
*/
function fixFilePaths(allFunctions, dir) {
dir = path.normalize(dir);
allFunctions.forEach((func) => {
var file = path.normalize(func.file);
if (file.substr(0, dir.length) == dir) {
file = file.replace(dir, "");
if (file[0] == '/') { file = file.substr(1); }
}
func.file = file;
});
return allFunctions;
}
module.exports = {
run
}