hx_watch
Version:
none
240 lines (193 loc) • 6.7 kB
JavaScript
/**
* @description: 文件监听,执行cmd命令小工具
* @author 王鸿兴
* @version 1.0.1
*/
var childProcess = require('child_process');
var fs = require('fs');
var path = require('path');
var util = require('util');
var crypto = require('crypto');
module.exports = (function () {
'use strict';
var watch = function(){};
var wp = watch.prototype;
wp.init = function(){
this.running = false;
this.md5arr = {};
this.newMd5 = {};
console.log("开始监听...")
this._checkCache();
};
wp._checkCache = function(){
var that = this;
if(this.running){
this._end(false);
return;
}
if(this.md5arr.length){
that._compileMd5();
return;
}
fs.readdir("./.watch-cache" , function(err , files){
var config = null;
var md5arr = null;
if(err){
fs.mkdirSync("./.watch-cache");
}else {
try{
config = fs.readFileSync("./.watch-cache/config").toString();
}catch(e){config = null}
try{
md5arr = JSON.parse(fs.readFileSync("./.watch-cache/cache").toString());
}catch(e){md5arr = null}
}
that.md5arr = md5arr;
if(!config){
console.log("请输入:相对路径|命令(例:html/|grunt build-html 回车)");
getInput(function(result){
var data = result.split('|' , 2);
that.path = data[0].replace(/[\r\n]/g,'');
that.cmd = data[1].replace(/[\r\n]/g,'');
fs.writeFile('./.watch-cache/config' , 'path="'+that.path+'";\r\ncmd="'+that.cmd+'";',function(){
that._compileMd5();
})
})
}else{
var array = config.match(/[a-z]*="[^\n";]*"(?=;)/g);
var configObj = {};
array.forEach(function(a){
configObj[a.split('=')[0]] = trim(a.split('=')[1].replace(/(^")|("$)/g , ''))
});
if(configObj.path && configObj.cmd){
that.path = configObj.path;
that.cmd = configObj.cmd;
that._compileMd5();
}else {
throw new Error("配置文件错误")
}
}
})
};
wp._compileMd5 = function(){
var that = this;
this._start();
var allFolder = getAllFolder(this.path);
this.newMd5.length = 0;
var str,md5str;
for(var i=0;i<allFolder.length;i++){
try{
str = fs.readFileSync(allFolder[i]);
md5str = crypto.createHash("md5").update(str).digest("hex");
this.newMd5[allFolder[i]] = md5str;
}catch (e){
continue;
}
}
this.newMd5.length = allFolder.length;
var hasChangeFile = [];
if(this.md5arr && this.md5arr.length && this.md5arr.length == this.newMd5.length){
var count = 0;
for(var key in this.md5arr){
if(key!=="length"){
if((key in this.newMd5) && this.newMd5[key]==this.md5arr[key])count++;
else{hasChangeFile.push(key)}
}
}
if(count == this.newMd5.length){
this._end(false);
this.running = false;
return;
}
}
allFolder.length = 0;
console.log("发生变动的文件:"+hasChangeFile.join(","))
this._execCmd()
};
wp._execCmd = function(){
var that = this;
console.log('执行命令' + this.cmd);
childProcess.exec(this.cmd, function(err, stdout, stderr) {
if(!err)console.log(stdout);
that._end(true);
that.running = false;
fs.writeFile('./.watch-cache/cache' , JSON.stringify(that.newMd5) , function(){
that.md5arr = that._simpleClone(that.newMd5);
that.newMd5 = {};
});
})
};
wp._start = function(){
this.running = true;
this.timesump = new Date();
};
wp._end = function(showtime){
var that = this;
if(showtime){
var newtime = new Date();
console.log("执行花费时间:"+(newtime - this.timesump));
console.log("当前时间:"+newtime)
}
setTimeout(function(){
that._checkCache();
} , 100)
}
wp._simpleClone = function(obj){
var result = {};
if(util.isArray(obj))return obj.slice(0);
for(var key in obj){
if(typeof key == "object"){
result[key] = this._simpleClone(obj[key])
}else {
result[key] = obj[key]
}
}
return result;
};
//进入输入状态
function getInput(callback) {
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', function(chunk) {
process.stdin.pause();
callback(chunk);
});
}
function getAllFolder(folderPath){
folderPath = trim(folderPath);
var isDir = false;
try{
isDir = fs.lstatSync(folderPath).isDirectory();
}catch(e){
isDir = false
}
if(!isDir){
return [folderPath]
}
var arr = [];
dealPath(folderPath);
return arr;
function dealPath(p){
var files = fs.readdirSync(p);
for(var i=0;i<files.length;i++){
p = trim(p);
p += p.charAt(p.length-1)=="/"?"":"/";
try{
var status = fs.lstatSync(p + files[i]);
}catch(e){
continue;
}
if(status.isDirectory()){
if(files[i].charAt(0)==".")continue;
dealPath(p + files[i] + "/");
}else {
arr.push(p + files[i])
}
}
}
}
function trim(msg){
return msg.replace(/(^\s*)|(\s*$)/g , "")
}
return new watch();
})();