-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.js
191 lines (177 loc) · 5.57 KB
/
main.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
//
// This program uses bdParse to determine all AMD dependencies for a set of Javascript resources. The
// program also demonstrates a basic template for loading AMD modules in a node.js program using bdLoad.
//
// The program processes all .js files that exist in a file hierarchy rooted as a location given by
// the command line argument "root", excluding all files that have "/nls/" in their path (typically, these
// are i18n bundles). Processing includes...
//
// * reading the resource
// * using bdParse to convert the resource contents into an AST
// * traversing the AST, looking for applications of the function define, and then traversing
// the argument tree for any such applications to find the AMD module name and dependencies.
//
// The program is constructed as follows:
//
// 1. bdLoad is instantiated and initialized; it is used to load AMD modules within node.
// 2. the command line is processed
// 3. the "find" program is used to traverse the file hierarchy given by the command line
// 4. Each candidate resource in the heirarchy is read, parsed, and the resulting AST traversed to
// find and AMD dependencies. All module identifiers and found dependencies are tracked in the
// variable deps;
// 5. deps is traversed for each module, writing the discovered dependency tree to stdout. Note: the tree
// is not fully traversed since this gets tedious for a real program; instead, when a dependency is encountered
// for the *second* time it is prefixed with a "^", directing the user's attention to a previous dump of the
// particular module's dependency tree. Any circular dependencies are noted by adding "**" after the name.
//
// Two command line arguments are recognized:
//
// * "--root" or "-r": the root of the file hierarchy to traverse
// * "--name" 0r "-n": the package name (if any) assumed to reside at root
//
// For example, from the bdParse/demo/trace-deps-tree directory, issuing the command
//
// node main.js -r ~/dev/bdParse/lib -n bdParse
//
// will result in the following output:
//
// bdParse/tokenize
// bdParse/types
// bdParse/types
// bdParse/asn
// bdParse/types
// bdParse/main
// bdParse/types
// bdParse/tokenize
// bdParse/types
// bdParse/parse
// bdParse/types
// bdParse/asn
// bdParse/types
// bdParse/asn
// bdParse/types
// bdParse/parse
// bdParse/types
// bdParse/asn
// bdParse/types
// bdParse/dump
// bdParse/types
// bdParse/asn
// bdParse/types
//
//
// load, instantiate, and configure bdLoad
var loader= require("../../../bdLoad/lib/node").boot({
baseUrl:__dirname + "/../../../",
packages: [{
name:"bdParse"
},{
name:"traceDeps",
location:"bdParse/demo/trace-deps-tree",
lib:"."
}]
});
// process the command line to get the root of the directory tree to traverse
var
// the root directory to traverse
root,
// the name of the hierarchy rooted at root
name= "",
illegalArgumentValue= function(name, pos) {
return new Error("Expected argument value for " + name);
};
for (var argv= process.argv, arg, i= 2, end= argv.length; i<end;) {
arg= argv[i++];
switch (arg) {
case "-r":
case "--root":
if (i<end) {
root= argv[i++];
} else {
throw illegalArgumentValue("root", i);
}
break;
case "-n":
case "--name":
if (i<end) {
name= argv[i++] + "/";
} else {
throw illegalArgumentValue("name", i);
}
break;
}
}
/*
var noFindTest= [
"../../lib/tokenize.js",
"../../lib/types.js",
"../../lib/asn.js",
"../../lib/main.js",
"../../lib/parse.js",
"../../lib/dump.js"
];
*/
loader.require(["bdParse", "traceDeps/trace"], function(bdParse, trace) {
// execute find <root> -name "*.js" -and -not -path "*/nls/*"
var
findResult= "",
errorMessage= "",
find= require("child_process").spawn("find", [root, "-name", "*.js", "-and", "-not", "-path", "*/nls/*"]);
// gather output into findResult
find.stdout.on('data', function (data) {
findResult+= data.toString("ascii");
});
// gather error outputint errorMessage
find.stderr.on('data', function (data) {
errorMessage+= data.toString("ascii");
});
// upon completion of find command...
find.on("exit", function(code, signal) {
if (code) {
console.log("Failed to find source files; find error:\n" + errorMessage);
return;
}
// for each filename found, read the file contents and do deps tracing; keep results in modules
var
pathLength= root.length + 1,
modules= {};
bdParse.split(findResult).forEach(function(filename) {
//noFindTest.forEach(function(filename) {
if (filename.length) {
var text= require("fs").readFileSync(filename, "utf8");
if (text) {
trace(text, name + filename.substring(pathLength).replace(/\.js$/, ""), modules);
} else {
console.log("Unable to read " + filename);
}
}
});
// for each module; traverse the discovered dependency tree and dump the results to stdout
var
seen, visited,
write= process.stdout.write,
dump= function(module, indent) {
if (indent.length) {
process.stdout.write(indent + module + "\n");
} else {
process.stdout.write(module + ":\n");
}
seen[module]= visited[module]= 1;
modules[module] && modules[module].forEach(function(mid) {
if (visited[mid]) {
process.stdout.write(indent + " " + mid + "**\n");
} else if (seen[mid]) {
process.stdout.write(indent + " ^" + mid + "\n");
} else {
dump(mid, indent + " ");
}
});
delete visited[module];
};
for (var p in modules) {
seen= {};
visited= {};
dump(p, "");
}
});
});