Grunt watch:仅上传已更改的文件

时间:2013-12-05 18:45:35

标签: ssh gruntjs grunt-contrib-watch

related

我能够使用grunt-ssh为我的开发服务器设置一个Grunt任务到SFTP文件:

sftp: {
    dev: {
        files: {
            './': ['**','!{node_modules,artifacts,sql,logs}/**'],
        },
        options: {
            path: '/path/to/project',
            privateKey: grunt.file.read(process.env.HOME+'/.ssh/id_rsa'),
            host: '111.111.111.111',
            port: 22,
            username: 'marksthebest',
        }
    }
},

但是当我运行它时会上传所有内容。有数千个文件。每次修改文件时,我都没有时间等待他们逐个上传。

如果我更改了文件,如何设置手表只上传我更改过的文件?

(好奇的是,服务器是本地网络上的虚拟机。它运行在不同的操作系统上,设置与我的本地机器更相似。如果我能正常工作,上传应该是闪电般快速的)

5 个答案:

答案 0 :(得分:7)

您需要的是grunt-newer,这是一项专门用于根据刚刚更改的文件更新任何任务配置的任务,然后运行它。示例配置可能如下所示:

watch: {
  all: {
    files: ['**','!{node_modules,artifacts,sql,logs}/**'],
    tasks: ['newer:sftp:dev']
  }
}

答案 1 :(得分:5)

您可以执行grunt-contrib-watch的{​​{3}}。 您基本上需要处理监视事件,修改sftp文件配置以仅包含已更改的文件,然后让grunt运行sftp任务。

这样的事情:

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        secret: grunt.file.readJSON('secret.json'),
        watch: {
            test: {
                files: 'files/**/*',
                tasks: 'sftp',
                options: {
                    spawn: false
                }
            }
        },
        sftp: {
          test: {
            files: {
              "./": "files/**/*"
            },
            options: {
              path: '/path/on/the/server/',
              srcBasePath: 'files/',
              host: 'hostname.com',
              username: '<%= secret.username %>',
              password: '<%= secret.password %>',
              showProgress: true
            }
          }
        }
    }); // end grunt.initConfig

    // on watch events configure sftp.test.files to only run on changed file
    grunt.event.on('watch', function(action, filepath) {
        grunt.config('sftp.test.files', {"./": filepath});
    });

    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-ssh');
};

注意&#34; spawn:false&#34;选项,以及在事件处理程序中设置配置所需的方式。

注意2:此代码一次上传一个文件,在同一个using the watch event中有更强大的方法。

答案 2 :(得分:3)

你可以通过Grunt实现这一目标:

  • 咕噜-的contrib手表

  • 咕噜-rsync的

首先要做的事情是:我使用的是Docker容器。我还在我的Docker Container中添加了一个公共SSH密钥。所以我上传到我的&#34;遥控器&#34;容器只有在我的本地环境中使用此Grunt任务更改的文件:

'use strict';

module.exports = function(grunt) {

    grunt.initConfig({

        rsync: {
            options: {
                args: ['-avz', '--verbose', '--delete'],
                exclude: ['.git*', 'cache', 'log'],
                recursive: true
            },
            development: {
                options: {
                    src: './',
                    dest: '/var/www/development',
                    host: 'root@www.localhost.com',
                    port: 2222
                }
            }
        },

        sshexec: {
            development: {
                command: 'chown -R www-data:www-data /var/www/development',
                options: {
                    host: 'www.localhost.com',
                    username: 'root',
                    port: 2222,
                    privateKey: grunt.file.read("/Users/YOUR_USER/.ssh/id_containers_rsa")
                }
            }
        },

        watch: {
            development: {
                files: [
                'node_modules',
                'package.json',
                'Gruntfile.js',
                '.gitignore',
                '.htaccess',
                'README.md',
                'config/*',
                'modules/*',
                'themes/*',
                '!cache/*',
                '!log/*'
                ],
                tasks: ['rsync:development', 'sshexec:development']
            }
        },

    });

    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-rsync');
    grunt.loadNpmTasks('grunt-ssh');

    grunt.registerTask('default', ['watch:development']);
};

祝你好运,快乐黑客!

答案 3 :(得分:2)

我最近遇到了类似的问题,我只想上传已更改的文件。我只使用grunt-exec。如果您拥有ssh对服务器的访问权限,则可以更高效地完成此任务。我还创建了一个被rsync.json忽略的git,因此协作者可以拥有自己的rsync数据。

好处是,如果有人做出改变,它会自动上传到他们的舞台。

    // Watch - runs tasks when any changes are detected.
    watch: {
        scripts: {
            files: '**/*',
            tasks: ['deploy'],
            options: {
                spawn: false
            }
        }
    }

我的部署任务是一个注册任务,它编译脚本然后运行exec:deploy

   // Showing exec:deploy task 
   // Using rsync with ssh keys instead of login/pass
    exec: {
        deploy: {
            cmd: 'rsync public_html/* <%= rsync.options %> <%= rsync.user %>@<%= rsync.host %>:<%=rsync.path %>'
    }

你看到很多<%= rsync %>的东西?我用它来获取git进入的rysnc.json信息。我只有这个,因为这是一个团队工作流程。

// rsync.json
{
  "options": "-rvp --progress -a --delete -e 'ssh -q'",
  "user": "mmcfarland",
  "host": "example.com",
  "path": "~/stage/public_html"
}

确保您在grunt中定义了rsync.json

module.exports = function(grunt) {

  var rsync = grunt.file.readJSON('path/to/rsync.json');
  var pkg = grunt.file.readJSON('path/to/package.json');

  grunt.initConfig({
    pkg: pkg,
    rsync: rsync,

答案 4 :(得分:0)

我认为将一次更改的所有内容上传到登台服务器并不是一个好主意。在登台服务器上工作也不是一个好主意。您必须配置本地计算机服务器,与登台/生产

相同

在部署时,最好上传一次。

您可以使用grunt-contrib-compress存档所有文件。并使用grunt-ssh作为1个文件推送它们,然后在服务器上提取它,这将会快得多。

压缩任务的例子:

compress: {
            main: {
                options:{
                    archive:'build/build.tar.gz',
                    mode: 'tgz'
                },
                files: [
                    {cwd: 'build/', src: ['sites/all/modules/**'], dest:'./'},
                    {cwd: 'build/', src: ['sites/all/themes/**'], dest:'./'},
                    {cwd: 'build/', src: ['sites/default/files/**'], dest:'./'}
                ]
            }
        }

PS:没想过rsync grunt模块。 我知道这可能不是你想要的。但我决定以独立的答案创建我的答案。