forked from Abacus/Abacus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJakefile.js
326 lines (257 loc) · 6.75 KB
/
Jakefile.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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
var // Dependency References
fs = require( "fs" ),
_ = require( "underscore" ),
jshint = require( "jshint" ).JSHINT,
colors = require( "colors" ),
uglifyjs = require( "uglify-js" ),
Buffer = require( "buffer" ).Buffer,
zlib = require( "zlib" ),
dateFormat = require( "dateformat" ),
stats = require( "stats" ),
cp = require("child_process"),
exec = cp.exec,
spawn = cp.spawn,
assert = require( "assert" ),
child;
var // Shortcut References
slice = Array.prototype.slice,
now = new Date();
var // Program References
$$ = {},
// Get options, defaults merged with build.json file.
config = _.extend({}, true, {
// Meta Build Info
"meta": {
"buildDate": dateFormat( now, "m/d/yyyy" )
},
// Overridden with build.json
"files": {},
// License Banner Template
"banner": [
"// <%= label %> - v<%= version %> - <%= buildDate %>",
"// <%= homeurl %>",
"// <%= copyright %>; Licensed <%= license.join(', ') %>"
].join( "\n" ),
// JSHint Optional Settings
"jshint": {
unused: true,
unuseds: true,
devel: true,
undef: true,
noempty: true,
evil: true,
forin: false,
maxerr: 100,
eqnull: true
// "curly": true,
// "eqnull": true,
// "immed": true,
// "newcap": true,
// "noarg": true,
// "undef": true,
// "browser": true,
// "predef": [ "jQuery" ]
},
// Uglify Optional Settings
"uglify": {
"mangle": {
"except": [ "$" ]
},
"squeeze": {},
"codegen": {}
}
},
readJson( "build.json", true )
),
// Setup Distribution File Banner (License Block)
banner = _.template( typeof config.banner == "string" ? config.banner : "" );
// Logging Utility Functions
function header( msg ) {
writeln( "\n" + msg.underline );
}
function write( msg ) {
process.stdout.write( (msg != null && msg) || "" );
}
function writeln( msg ) {
console.log( (msg != null && msg) || "" );
}
function ok( msg ) {
writeln( msg ? "\n>> ".green + msg : "OK".green );
}
function error( msg ) {
writeln( msg ? "\n>> ".red + msg : "ERROR".red );
}
// Read a file.
function readFile( filepath ) {
var src;
write( "Reading " + filepath + "..." );
try {
src = fs.readFileSync( filepath, "UTF-8" );
ok();
return src;
} catch( e ) {
error();
fail( e.message );
}
}
// Write a file.
function writeFile( filepath, contents, silent ) {
// if ( config.nowrite ) {
// writeln('Not'.underline + ' writing ' + filepath + ' (dry run).');
// return true;
// }
if ( arguments.length < 3 ) {
silent = true;
}
silent || write( "Writing " + filepath + "..." );
try {
fs.writeFileSync( filepath, contents, "UTF-8" );
} catch( e ) {
error();
fail( e );
}
ok();
return true;
}
// Read and parse a JSON file.
function readJson( filepath, silent ) {
var result;
silent || write( "Reading " + filepath + "..." );
try {
result = JSON.parse(
fs.readFileSync( filepath, "UTF-8" )
);
} catch( e ) {
silent || error();
fail( e.message );
}
silent || ok();
return result;
}
// # Lint some source code.
// From http://jshint.com
function hint( src, path ) {
write( "Validating with JSHint...");
if ( jshint( src, config.jshint ) ) {
ok();
} else {
error();
jshint.errors.forEach(function( e ) {
if ( !e ) { return; }
var str = e.evidence ? e.evidence.inverse : "";
str = str.replace( /\t/g, " " ).trim();
error( path + " [L" + e.line + ":C" + e.character + "] " + e.reason + "\n " + str );
});
fail( "JSHint found errors." );
}
}
// # Minify with UglifyJS.
// From https://github.com/mishoo/UglifyJS
function uglify( src ) {
write( "Uglifying..." );
var jsp = uglifyjs.parser,
pro = uglifyjs.uglify,
ast;
try {
ast = jsp.parse( src );
ast = pro.ast_mangle( ast, config.uglify.mangle || {});
ast = pro.ast_squeeze( ast, config.uglify.squeeze || {});
src = pro.gen_code( ast, config.uglify.codegen || {});
} catch( e ) {
error();
error( "[L" + e.line + ":C" + e.col + "] " + e.message + " (position: " + e.pos + ")" );
fail( e.message );
return false;
}
ok();
return src;
}
// Return deflated src input.
function gzip( src ) {
return zlib.deflate( new Buffer( src ) );
}
// Jake Tasks
desc( "Hint & Minify" );
task( "default", [ "hint", "min" ], function() {
// Nothing
});
desc( "Validate with JSHint." );
task( "hint", function() {
header( "Validating with JSHint" );
_.keys( config.files ).forEach(function( minpath ) {
var files = config.files[ minpath ],
concat = files.src.map(function( path ) {
var src = readFile( path );
config.jshint.devel = config.jshint.debug = files.debug;
if ( files.prehint ) {
hint( src, path );
}
return src;
}).join( "\n" );
if ( files.src.length ) {
write( "Hinting concatenated source: " + files.src.length + " scripts..." );
ok();
if ( files.posthint ) {
hint( concat, "post" );
}
}
});
});
desc( "Minify with Uglify-js." );
task( "min", function() {
header( "Minifying with Uglify-js" );
_.keys( config.files ).forEach(function( minpath ) {
var file = config.files[ minpath ],
concat = file.src.map( function( path ) {
return readFile( path );
}).join( "\n" ),
intro, fullpath, min;
fullpath = minpath + ".js";
minpath = minpath + ".min.js"
// Generate intro block with banner template,
// Inject meta build data
intro = banner( _.extend( file.meta, config.meta ) );
// Without a newline, the min source code will run on the same
// Line as the intro lic/banner block
if ( intro ) {
intro += "\n";
}
// Provide information about current file being built
if ( file.src.length ) {
write( "Concatenating " + file.src.length + " script(s)" );
ok();
}
// Write full sized, concatenated source
writeFile( fullpath, concat, false );
// Minify/Uglify and Write compressed, concatenated source
if ( min = uglify( concat ) ) {
min = intro + min;
if ( writeFile( minpath, min, false ) ) {
ok( "Compressed size: " + (gzip( min ).length + "").yellow + " bytes gzipped (" + ( min.length + "" ).yellow + " bytes minified)." );
}
}
});
});
desc( "View static analysis of JavaScript program code" );
task( "stats", [], function() {
header( "Statistics" );
var exts = [ ".js", ".min.js" ],
comp, stat, diff, color;
_.keys( config.files ).forEach(function( file ) {
exts.forEach(function( ext ) {
stat = stats.parse( readFile( file + ext ) );
_.keys( stat ).forEach( function( key, idx ) {
write( " " + key + ": " + this[ key ] );
if ( comp ) {
diff = (comp[ key ] - this[ key ]);
color = Math.abs(diff) > 0 ? "red" : "grey";
write( " (-" + (diff + "")[ color ] + ")" );
}
write( "\n" );
}, stat );
if ( comp == null ) {
comp = stat;
}
});
});
});