UNPKG

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