Search code examples
javascriptnode.jsgruntjsgrunt-contrib-watchgrunt-ssh

Grunt-ssh and grunt-watch to sftp on changed files


Im trying to get grunt-ssh sftp to work with grunt-watch to only send modified files. I manage to get this to work but with a wired problem

my grunt config

grunt.initConfig({
    watch: {
        upload: {
            files: ['*.*'],
            tasks: ['sftp'],
            options: {
                spawn: false,
            },
        }
    },
    sftp:{
        upload:{
            options: {
                host: '192.168.10.10',
                username: 'blah',
                password: 'blah',
                path:'/home/vagrant/Sites/test/',
                showProgress: true,
            },
            files:{'./': []}
        },

    },
});

function on watch event to modify the config

var changedFiles = {'./': []};
var onChange = grunt.util._.debounce(function() {
    grunt.config('sftp.upload.files', changedFiles);
    changedFiles = {'./': []};
    console.log(grunt.config('sftp.upload.files'))
}, 275);
grunt.event.on('watch', function(action, filepath) {
    changedFiles['./'].push(filepath);
    onChange();
});

This it the output from grunt

Running "watch" task
Waiting...
{ './': [ 'Gruntfile.js' ] }
>> File "Gruntfile.js" changed.

Running "sftp:upload" (sftp) task
Gruntfile.js [====================] 100% of 6KB
Created 1 directories, copied 1 files

Running "watch" task
Completed in 0.617s at Fri Jun 16 2017 11:47:56 GMT+0100 (BST) - 
Waiting...

Reloading watch config...

Running "watch" task
Waiting...
{ './': [ 'affiliate_with_log.php', 'Gruntfile.js' ] }
>> File "affiliate_with_log.php" changed.
>> File "Gruntfile.js" changed.

Running "sftp:upload" (sftp) task
affiliate_with_log.php [====================] 100% of 10KB
Gruntfile.js [====================] 100% of 6KB
Created 1 directories, copied 2 files

Running "watch" task
Completed in 0.546s at Fri Jun 16 2017 11:48:08 GMT+0100 (BST) - 
Waiting...
>> File "affiliate_with_log.php" changed.
>> File "img.php" changed.

Running "sftp:upload" (sftp) task
{ './': [ 'affiliate_with_log.php', 'img.php' ] }
{ './': [ 'affiliate_with_log.php', 'img.php' ] }
{ './': [ 'affiliate_with_log.php', 'img.php' ] }
affiliate_with_log.php [====================] 100% of 10KB
Gruntfile.js [====================] 100% of 6KB
Created 1 directories, copied 2 files

Running "watch" task 
Completed in 0.538s at Fri Jun 16 2017 11:48:19 GMT+0100 (BST) - 
Waiting...
>> File "img.php" changed.

Running "sftp:upload" (sftp) task
{ './': [ 'img.php' ] }
{ './': [ 'img.php' ] }
{ './': [ 'img.php' ] }
affiliate_with_log.php [====================] 100% of 10KB
img.php [====================] 100% of 877B
Created 1 directories, copied 2 files

in this output you can see that the console log of the files is correct every time but it doesn't always seem to upload to correct file and I cant work out why. any help would be much appreciated


Solution

  • I resolved this by adding a wait before the sftp task to make sure the config had time to update

    grunt.registerTask('wait', 'Wait for a set amount of time.', function() {
    
        delay = 1;
    
        var d = delay ? delay + ' second' + (delay === '1' ? '' : 's') : 'forever';
        grunt.log.write('Waiting ' + d + '...');
        // Make this task asynchronous. Grunt will not continue processing
        // subsequent tasks until done() is called.
        var done = this.async();
        // If a delay was specified, call done() after that many seconds.
        if (delay) { setTimeout(done, delay * 1000); }
    
    });
    

    the changed the watch task:

    watch: {
            upload: {
                files: ['./*.*', './resources/**/*.*', './protected/**/*.*'],
                tasks: ['wait', 'sftp:upload'],
                options: {
                    spawn: false,
                },
            }
        },