forked from jonycheung/deadsimple-less-watch-compiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathless-watch-compiler.js
198 lines (180 loc) · 6.21 KB
/
less-watch-compiler.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
/* Copyright 2012, Jonathan Cheung Licensed and released under the MIT
license. Refer to MIT-LICENSE.txt.
A nodejs script that allows you to watch a folder for changes and
compile the less css files into another folder.
Always give credit where it's due. Parts of this script is modified
from Mikeal Rogers's watch script (https://github.com/mikeal/watch)
Usage: node less-watch-compiler.js FOLDER_TO_WATCH FOLDER_TO_OUTPUT
Example: "node less-watch-compiler.js less css" will watch ./less folder
and compile the less css files into ./css when they are added/changed
*/
var allowedExtensions = ["less"];
var sys = require('util')
, fs = require('fs')
, path = require('path')
, events = require('events')
, exec = require('child_process').exec;
// Check to see if we have the correct number of arguments
var argvs = process.argv.slice(2);
if (!argvs[0] || !argvs[1]){
console.log("Missing arguements");
console.log("\tnode less-watch-compiler.js FOLDER_TO_WATCH FOLDER_TO_OUTPUT");
console.log("\tExample:");
process.exit(1);
}
// Walk the directory tree
function walk (dir, options, callback, initCallback) {
if (!callback) {callback = options; options = {}}
if (!callback.files) callback.files = {};
if (!callback.pending) callback.pending = 0;
callback.pending += 1;
fs.stat(dir, function (err, stat) {
if (err) return callback(err);
callback.files[dir] = stat;
fs.readdir(dir, function (err, files) {
if (err) return callback(err);
callback.pending -= 1;
files.forEach(function (f, index) {
f = path.join(dir, f);
callback.pending += 1;
fs.stat(f, function (err, stat) {
var enoent = false
, done = false;
if (err) {
if (err.code !== 'ENOENT') {
return callback(err);
} else {
enoent = true;
}
}
callback.pending -= 1;
done = callback.pending === 0;
if (!enoent) {
if (options.ignoreDotFiles && path.basename(f)[0] === '.') return done && callback(null, callback.files);
if (options.filter && options.filter(f, stat)) return done && callback(null, callback.files);
callback.files[f] = stat;
if (stat.isDirectory()) {
walk(f, options, callback);
}else{
initCallback&&initCallback(f);
}
if (done) callback(null, callback.files);
}
})
})
if (callback.pending === 0) callback(null, callback.files);
})
if (callback.pending === 0) callback(null, callback.files);
})
}
//Setup fs.watchFile() for each file.
var watchTree = function ( root, options, watchCallback, initCallback ) {
if (!watchCallback) {watchCallback = options; options = {}}
walk(root, options, function (err, files) {
if (err) throw err;
var fileWatcher = function (f) {
fs.watchFile(f, options, function (c, p) {
// Check if anything actually changed in stat
if (files[f] && !files[f].isDirectory() && c.nlink !== 0 && files[f].mtime.getTime() == c.mtime.getTime()) return;
files[f] = c;
if (!files[f].isDirectory()) {
if(options.ignoreDotFiles && (path.basename(f)[0] === '.')) return;
if(options.filter&& options.filter(f, files[f])) return;
watchCallback(f, c, p);
}else {
fs.readdir(f, function (err, nfiles) {
if (err) return;
nfiles.forEach(function (b) {
var file = path.join(f, b);
if (!files[file]) {
fs.stat(file, function (err, stat) {
if(options.ignoreDotFiles && (path.basename(b)[0] === '.')) return;
if(options.filter&& options.filter(b, files[b])) return;
watchCallback(file, stat, null);
files[file] = stat;
fileWatcher(file);
})
}
})
})
}
if (c.nlink === 0) {
// unwatch removed files.
delete files[f]
fs.unwatchFile(f);
}
})
}
fileWatcher(root);
for (var i in files) {
fileWatcher(i);
}
watchCallback(files, null, null);
},
initCallback);
}
// String function to retrieve the filename without the extension
function getFilenameWithoutExtention(string){
//extract filename (xxx.less)
//strip out the extension
var filename = string.replace(/^.*[\\\/]/, '').split(".")[0];
return filename
}
// String function to retrieve the file's extension
function getFileExtension(string){
var extension = string.split(".").pop();
if (extension == string) return ""
else
return extension;
}
// Here's where we run the less compiler
function compileCSS(file){
var filename = getFilenameWithoutExtention(file);
// Updated the command to properly out put to a file
var command = "lessc "+file.replace(/\s+/g,"\\ ")+" > "+argvs[1]+"/"+filename.replace(/\s+/g,"\\ ")+".css";
console.log("Command: '"+command+"'");
// Run the command
exec(command, function (error, stdout, stderr){
if (error !== null) {
console.log('exec error: ' + error);
console.log("stdout : "+stdout)
console.log("stderr : "+stderr)
}
});
}
// This is the function we use to filter the files to watch.
function filterFiles(f, stat){
var filename = getFilenameWithoutExtention(f);
var extension = getFileExtension(f);
if (filename.substr(0,1) == "_" ||
filename.substr(0,1) == "." ||
filename == "" ||
allowedExtensions.indexOf(extension) == -1
)
return true;
else{
return false;
}
}
// Here's where we setup the watch function
watchTree(
argvs[0],
{interval: 500, ignoreDotFiles:true,filter:filterFiles},
function (f, curr, prev) {
if (typeof f == "object" && prev === null && curr === null) {
// Finished walking the tree
return;
} else if (curr.nlink === 0) {
// f was removed
console.log(f +" was removed.")
}else {
// f is a new file or changed
console.log("The file: "+f+ " was changed.")
console.log("Recompiling CSS.. "+Date());
compileCSS(f);
}
},
function(f){
compileCSS(f);
}
);