2013-04-02 43 views
4

Grunt通知:https://github.com/dylang/grunt-notify是伟大的。但是,它似乎有点有限。据我所知,我所有的消息都需要预先生成。所以第一个问题是我如何生成通知?Grunt任务输出然后调用grunt-notify

接下来,似乎grunt通知基于某些任务的错误或成功的触发器。我猜基于std in/out/err?如果某些任务不使用这些任务,那么这个问题就会消失。如果有编译错误,grunt compass不使用stderr。那么如何在发生错误时运行grunt notify?这会导致下一个问题。我如何从咕噜任务中获取控制台输出或stderr?

回答

7

首先,使用growl。使用起来简单而灵活。要安装咆哮

npm install growl --save-dev 

然后,你需要hook到进程的标准错误/输出流。这样,每当新邮件到达stderr/out流时,您都可以创建通知。

这就是我创建的。我做了一个CommonJS的模块,它增加了钩:

  • grunt.fail.warn()grunt.fail.fatal()
  • grunt.log.warn()grunt.log.error()
  • grunt.warn()
  • process.stderr.write()
  • process.stdout.write()(误差线)
  • (孩子)process.stderr.write()
  • (孩子)process.stdout.write()(错误行)

它或多或少工作,但它可能需要一些调整。

任务/ lib目录/ notify.js

(function (module) { 
    var grunt = require('grunt'), 
     growl = require('growl'), 
     Buffer = require('buffer').Buffer; 

    function notify(obj, title) { 
     if (obj) { 
      var message = Buffer.isBuffer(obj) ? obj.toString() : (obj.message || obj); 
      var msg = grunt.log.uncolor(message); 

      if (msg.length > 0) { 
       growl(msg, { 
        title: title, 
        image: 'Console' 
       }); 
      } 
     } 
    } 

// add a hook to grunt.fail.warn(), grunt.fail.fatal() 
    ['warn', 'fatal'].forEach(function (level) { 
     grunt.util.hooker.hook(grunt.fail, level, function(obj) { 
      notify(obj); 
     }); 
    }); 

// add a hook to grunt.log.warn(), grunt.log.error() 
    ['warn', 'error'].forEach(function (level) { 
     grunt.util.hooker.hook(grunt.log, level, function(obj) { 
      notify(obj, level); 
     }); 
    }); 

// add a hook to grunt.warn() 
    grunt.util.hooker.hook(grunt, 'warn', function(obj) { 
     notify(obj, 'warn'); 
    }); 

// add a hook to process.stderr.write() 
    grunt.util.hooker.hook(process.stderr, 'write', function(obj) { 
     var messages = grunt.log.uncolor((Buffer.isBuffer(obj) ? obj.toString() : (obj.message || obj))).split('\n'); 
     messages.forEach(function (message) { 
      notify(message, 'stderr'); 
     }); 
    }); 

// add a hook to process.stdout.write() (only error lines) 
    grunt.util.hooker.hook(process.stdout, 'write', function(obj) { 
     var messages = grunt.log.uncolor((Buffer.isBuffer(obj) ? obj.toString() : (obj.message || obj))).split('\n'); 
     messages.forEach(function (message) { 
      if (message && message.indexOf('error ') > -1) { 
       notify(message, 'stdout'); 
      } 
     }); 
    }); 

// add a hook to child process stdout/stderr write() (only error lines) 
    grunt.util.hooker.hook(grunt.util, 'spawn', { 
     post: function(child) { 
      child.stderr.on('data', function (data) { 
       var messages = grunt.log.uncolor(data.toString()).split('\n'); 
       messages.forEach(function (message) { 
        notify(message, 'stderr'); 
       }); 
      }); 
      child.stdout.on('data', function (data) { 
       var messages = grunt.log.uncolor(data.toString()).split('\n'); 
       messages.forEach(function (message) { 
        if (message && message.indexOf('error ') > -1) { 
         notify(message, 'stdout'); 
        } 
       }); 
      }); 
     } 
    }); 
}) (module); 

然后你需要用require声明把它列入你的Gruntfile.js

module.exports = function (grunt) { 

    grunt.initConfig({ 
     ... 
    }); 
    require('./tasks/lib/notify'); 

    ... 
}; 

PS我已经放在该文件在tasks/lib/notify.js,但随意放置在别的地方。

+0

还没有机会测试它,但看起来不错。我想最初我们有一个与咕噜声的问题。没有咆哮或通知中心的人我们遇到了错误,这可能已经改变了? API绝对看起来更好。话虽如此,我可能会提交一个拉请求的变化,通过看看grunt-notify是如何做的,它不会失败。 – Parris

+0

我很抱歉,但我完全陌生,并且我认为这正是我想要的,但我不知道如何实现此文件。你能提供更多的解释吗? – Jason

+0

我已经添加了一个额外的部分。你需要在你的Gruntfile.js中添加一个require语句。 – asgoth