UNPKG

5.54 kBJavaScriptView Raw
1(function(){
2
3 var
4 watch = require( 'watch-tree-maintained' ),
5 async = require( 'asyncjs' ),
6 fs = require( 'fs' ),
7 colorize = require( 'colorize' ),
8 console = colorize.console,
9 util = require( 'util' ),
10 path = require( 'path' ),
11 inspect = util.inspect,
12 plugins = require('./plugins'),
13 _ = require('underscore'),
14 VERSION = require('../package.json').version;
15
16 module.exports.plugins = plugins;
17 module.exports.Compiler = Compiler;
18 module.exports.VERSION = VERSION;
19
20 function Compiler( rootDir, outputDir, watchMode, watchOpts ) {
21 this.rootDir = rootDir;
22 this.outputDir = outputDir;
23 this.watchMode = !!watchMode;
24 this.rules = [];
25 this.watchOpts = watchOpts || {};
26 this.waitTime = 100; // time to wait for write after noticing a change
27 return this;
28 }
29
30 var levelColorMap = {
31 'error' : 'red',
32 'success' : 'green',
33 'msg' : 'plain',
34 'info' : 'cyan',
35 'warn' : 'yellow'
36 };
37
38 Compiler.prototype.log = function( level, coloredPart, plainPart ) {
39 var color = levelColorMap[level],
40 outputString = colorize.ansify("#" + color + "[" + coloredPart + "]") + (plainPart ? ": " + plainPart : "");
41 util.log( outputString );
42 };
43
44 Compiler.prototype.start = function() {
45 var that = this,
46 watchMode = that.watchMode,
47 rootDir = that.rootDir,
48 outputDir = that.outputDir;
49 this.log('success', 'Auton v' + VERSION + ' starting...');
50 var opts = _.extend({
51 'sample-rate' : 5,
52 'ignore' : new RegExp('/[._]')
53 }, this.watchOpts);
54 var watcher = watch.watchTree(rootDir, opts);
55
56 var _compile = function(path){ return that._compile(path); };
57 var _delete = function(path){ return that._delete(path); };
58
59 watcher.on( 'filePreexisted', _compile );
60 watcher.on( 'fileCreated', _compile );
61 watcher.on( 'fileModified', _compile );
62 watcher.on( 'fileDeleted', _delete );
63 watcher.on( 'allPreexistingFilesReported', function(){
64 if (watchMode) {
65 that.log('info', "Entering watch mode");
66 } else {
67 that.log('info', "All files scanned");
68 watcher.end();
69 }
70 });
71 };
72
73 Compiler.prototype.addRule = function( test, outputFilenameFunction, ruleList ) {
74 this.rules.push({
75 test: test,
76 outputFilenameFunction: outputFilenameFunction,
77 ruleList: ruleList
78 });
79 };
80
81 Compiler.prototype.copy = function( test ) {
82 this.rules.push({
83 test: test,
84 outputFilenameFunction: function(type, filePath){ return (type === 'original' || type === '__age_check__') ? filePath : null; },
85 ruleList: [plugins.read, plugins.save]
86 });
87 };
88
89 Compiler.prototype.ignore = function( test ) {
90 this.rules.push({
91 test: test,
92 ignore: true,
93 });
94 };
95
96 function checkTest( test, target ) {
97 if (test instanceof RegExp && test.test(target) ) {
98 return true;
99 }
100 else if (typeof test === 'function' && test(target) === true) {
101 return true;
102 }
103 else if (typeof test === 'string' && test === target) {
104 return true;
105 }
106 }
107
108
109
110 Compiler.prototype._compile = function(path) {
111 path = path.replace(this.rootDir + "/", "");
112 for (i = 0, len = this.rules.length; i < len; i++) {
113 var rule = this.rules[i];
114 if (checkTest( rule.test, path )) {
115 if (rule.ignore) {
116 return;
117 }
118 this._runChain( path, rule, rule.ruleList );
119 return;
120 }
121 }
122
123 this.log( 'warn', "Skipped", path );
124 };
125
126 Compiler.prototype._delete = function(path) {
127
128 };
129
130 Compiler.prototype._runChain = function(file, rule, functions) {
131 var args = {
132 compiler: this,
133 rule: rule,
134 path: file,
135 save: { },
136 savedFilenames: [ ]
137 },
138 makeCyan = function(x){ return colorize.ansify("#cyan[" + x + "]"); },
139 go = function() {
140 async.list(functions).call(args).end(function(e){
141 if (e) {
142 args.compiler.log( 'error', "Error in "+file, "\n" + e.toString() + "\n" );
143 } else {
144 if (args.savedFilenames.length) {
145 args.compiler.log( 'success', file, "Saved " + args.savedFilenames.map(makeCyan).join(', ') );
146 } else {
147 args.compiler.log( 'success', file, 'OK!' );
148 }
149 // console.log(" COMPILED: " + file);
150 }
151 });
152 };
153
154 var ageCheckFilename = rule.outputFilenameFunction( '__age_check__', file );
155 if (ageCheckFilename) {
156 var infile = path.join( this.rootDir, file ),
157 outfile = path.join( this.outputDir, ageCheckFilename );
158 fs.stat( infile, function(err, infileStats){
159 if (err) {
160 args.compiler.log( 'error', 'couldnt stat '+infile, err);
161 return;
162 }
163 fs.exists( outfile, function(exists){
164 if (exists) {
165 fs.stat( outfile, function(err, outfileStats){
166 if (err) {
167 args.compiler.log( 'error', 'couldnt stat '+outfile, err);
168 return;
169 }
170
171 if (Date.parse(infileStats.mtime) > Date.parse(outfileStats.mtime)) {
172 setTimeout( go, args.compiler.waitTime );
173 }
174 });
175 } else {
176 setTimeout( go, args.compiler.waitTime );
177 }
178
179 });
180 });
181 } else {
182 setTimeout( go, args.compiler.waitTime );
183 }
184 };
185
186
187})();