Grunt task output then calling grunt-notify

后端 未结 1 1179
陌清茗
陌清茗 2021-02-06 15:18

Grunt notify: https://github.com/dylang/grunt-notify is great. However, it seems a bit limited. As far as I can tell all my messages need to be pre-generated. So the first quest

1条回答
  •  礼貌的吻别
    2021-02-06 15:56

    First of all, use growl. It is easy and flexible to use. To install growl:

    npm install growl --save-dev
    

    Then you need to hook into the stderr/out stream of the process. This way you can create a notification each time a new message arrives at the stderr/out stream.

    This is what I've created. I've made a CommonJs module which adds hooks to:

    • grunt.fail.warn(), grunt.fail.fatal()
    • grunt.log.warn(), grunt.log.error()
    • grunt.warn()
    • process.stderr.write()
    • process.stdout.write() (error lines)
    • (child) process.stderr.write()
    • (child) process.stdout.write() (error lines)

    It works more or less, but it may need some tweaking.

    tasks/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);
    

    Then you need to include it in your Gruntfile.js with a require statement:

    module.exports = function (grunt) {
    
        grunt.initConfig({
           ...
        });
        require('./tasks/lib/notify');
    
        ...
    };
    

    PS I've placed the file in tasks/lib/notify.js, but feel free to place it somewhere else.

    0 讨论(0)
提交回复
热议问题