4

Grunt 通知:https ://github.com/dylang/grunt-notify很棒。但是,它似乎有点有限。据我所知,我所有的消息都需要预先生成。所以第一个问题是如何生成通知?

接下来,似乎 grunt notify 会根据某些任务的错误或成功触发。我猜基于标准输入/输出/错误?这个问题的问题是如果某些任务不使用这些。如果有编译错误,grunt compass 不使用 stderr。那么当出现错误时如何运行 grunt notify 呢?这就引出了下一个问题。如何从 grunt 任务中获取控制台输出或标准错误?

4

1 回答 1

7

首先,使用咆哮。它易于使用且灵活。要安装咆哮

npm install growl --save-dev

然后你需要挂钩到进程的 stderr/out 流。这样,您可以在每次新消息到达 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);

然后你需要在你的Gruntfile.js中包含一个require声明:

module.exports = function (grunt) {

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

    ...
};

PS 我已将文件放在 中tasks/lib/notify.js,但请随意将其放在其他位置。

于 2013-04-03T07:46:44.253 回答