Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

bumped version

tidy up
added test-files
restructure exec with seperate callback function
starting doc
  • Loading branch information...
commit 54947025659961187243f08aea1f527099744a5b 1 parent 03e7845
Jan-Philip Loos authored
10 README.md
Source Rendered
... ... @@ -1,17 +1,17 @@
1   -# grunt-scp
  1 +# grunt-rsync
2 2
3   -Copy files to a (remote) machine running an SSH daemon.
  3 +Copy files to a (remote) machine running an SSH daemon with 'rsync'.
4 4
5 5 ## Getting Started
6 6
7   -*`scp` has to be installed on your system and be able to connect to the host without password (e.g. public key authentication)*
  7 +*`rsync` has to be installed on the local and remote system. `rsync` must be able to connect to the host without password (e.g. public key authentication)*
8 8
9   -Install with: `npm install grunt-scp`
  9 +Install with: `npm install grunt-rsyc`
10 10
11 11 Inside your `grunt.js` file add :
12 12
13 13 ``` javascript
14   -grunt.loadNpmTasks('grunt-scp');
  14 +grunt.loadNpmTasks('grunt-rsync');
15 15 ```
16 16
17 17 and a task named `scp` (see Configuration)!
10 grunt.js
@@ -37,14 +37,18 @@ module.exports = function (grunt) {
37 37 }
38 38 },
39 39
40   - scp: {
  40 + rsync: {
41 41 deploy: {
42   - src: 'test/',
  42 + files: {
  43 + 'a/b/c/': 'test/test-files/',
  44 + 'a/': 'test/test-files/one.txt',
  45 + 'a/b/': ['test/test-files/one.txt', 'test/test-files/ddd/xyz.txt']
  46 + },
43 47 options: {
44 48 host: "test.mygnia.de",
45 49 port: "22",
46 50 user: "jloos",
47   - path: "~"
  51 + remoteBase: "~/grunt-rsync-test"
48 52 }
49 53 }
50 54 }
14 package.json
... ... @@ -1,7 +1,7 @@
1 1 {
2 2 "name": "grunt-rsync",
3 3 "description": "Copy files to a (remote) machine with rsync",
4   - "version": "0.1.0",
  4 + "version": "0.1.1",
5 5 "homepage": "https://github.com/maxdaten/grunt-rsync",
6 6 "author": {
7 7 "name": "Jan-Philip Loos",
@@ -9,7 +9,7 @@
9 9 },
10 10 "repository": {
11 11 "type": "git",
12   - "url": "https://github.com/maxdaten/grunt-rsync"
  12 + "url": "https://github.com/maxdaten/grunt-rsync"
13 13 },
14 14 "bugs": {
15 15 "url": "https://github.com/maxdaten/grunt-rsync/issues"
@@ -35,5 +35,11 @@
35 35 "grunt-bump": "*",
36 36 "grunt-beautify": "*"
37 37 },
38   - "keywords": ["gruntplugin", "rsync", "copy", "remote", "scp"]
39   -}
  38 + "keywords": [
  39 + "gruntplugin",
  40 + "rsync",
  41 + "copy",
  42 + "remote",
  43 + "scp"
  44 + ]
  45 +}
108 tasks/rsync.js
@@ -9,33 +9,64 @@
9 9 module.exports = function (grunt) {
10 10 'use strict';
11 11
  12 + function rsyncCallback(error, stdout, stderr) {
  13 + grunt.log.writeln('stdout: ' + stdout);
  14 + grunt.log.writeln('stderr: ' + stderr);
12 15
  16 + grunt.log.writeln('err: ' + error);
  17 +
  18 + if (error) {
  19 + //done(false);
  20 + grunt.fail.fatal(error);
  21 + }
  22 + }
  23 +
  24 +
  25 + function doRsync(cmd, user, host, remoteBase, target, files) {
  26 + var exec = require('child_process').exec,
  27 + src = grunt.file.expand(files[target]),
  28 + dest = target;
  29 +
  30 + cmd.push(src.join(' '));
  31 +
  32 + // destination to copy
  33 + cmd.push(user + '@' + host + ':' + remoteBase + '/' + target); // TODO: normalize
  34 + cmd = cmd.join(' ');
  35 +
  36 + grunt.log.writeln( 'executing: ' + cmd );
  37 + grunt.log.write( 'starting transfer... ' );
  38 +
  39 + exec(cmd, rsyncCallback);
  40 + grunt.log.ok();
  41 + }
13 42
14 43 grunt.util = grunt.util || grunt.utils;
15 44
16 45 grunt.registerMultiTask('rsync', 'Copy files to a (remote) machine with rsync.', function () {
17 46
18   - var done = this.async(),
19   - exec = require('child_process').exec,
20   - src = this.file.src,
21   - dest = this.file.dest,
  47 + var done = this.async(),
  48 + files = grunt.helper('createFileMap', this.data.files),
  49 +
  50 +
22 51 // options
23   - dry = grunt.option('no-write'),
24   - host = this.data.options.host || 'localhost',
25   - user = this.data.options.user || 'getGitUser', // TODO system username or nothing?
26   - remoteBase = this.data.options.remoteBase || '~',
27   - verbose = grunt.option('verbose'),
28   - preserveTimes = this.data.options.preserveTimes,
  52 + dry = grunt.option('no-write'),
  53 + host = this.data.options.host || 'localhost',
  54 + user = this.data.options.user || 'getGitUser',
  55 +
  56 +
  57 + // TODO system username or nothing?
  58 + remoteBase = this.data.options.remoteBase || '~',
  59 + verbose = grunt.option('verbose'),
  60 + preserveTimes = this.data.options.preserveTimes,
29 61 preservePermissions = this.data.options.preservePermissions || true,
30   - compression = this.data.options.compression || true,
31   - recursive = this.data.options.recursive || true,
32   - additionalOptions = this.data.options.additionalOptions || '';
33   -
  62 + compression = this.data.options.compression || true,
  63 + recursive = this.data.options.recursive || true,
  64 + additionalOptions = this.data.options.additionalOptions || '';
  65 +
34 66 // setup the cmd
35 67 var command = ['rsync'];
36 68
37 69 // these flags must be set before the src/dest args
38   -
39 70 if (recursive) {
40 71 command.push('-r');
41 72 }
@@ -47,7 +78,7 @@ module.exports = function (grunt) {
47 78 if (preserveTimes) {
48 79 command.push('-t');
49 80 }
50   -
  81 +
51 82 if (preservePermissions) {
52 83 command.push('-p');
53 84 }
@@ -63,30 +94,27 @@ module.exports = function (grunt) {
63 94 command.push(additionalOptions);
64 95
65 96 // from this line on, the order of the args is relevant!
  97 + // files to copy
  98 + // save command before execute files-map wise
  99 + for (var target in files) {
  100 + // copy command
  101 + doRsync(command.slice(), user, host, remoteBase, target, files);
  102 + } // for in files
  103 + done(true);
66 104
  105 + });
67 106
68   - // files to copy
69   - command.push(grunt.file.expand(src).join(' '));
70   -
71   - // destination to copy
72   - command.push(user+'@' + host + ':' + remoteBase);
73   -
74   - command = command.join(' ');
75   -
76   - grunt.log.writeln('executing: ' + command );
77   - grunt.log.write('starting transfer...: ');
78   -
79   - exec(command, function (err, stdout, stderr) {
80   - if (stdout) {grunt.log.writeln(stdout);}
81   - if (stderr) {grunt.log.writeln(stderr);}
82   -
83   - if (err) {
84   - grunt.fail.fatal(err);
85   - done(false);
86   - } else {
87   - grunt.log.ok();
88   - done(true);
89   - }
90   - });
  107 + grunt.registerHelper('createFileMap', function (files) {
  108 + var map = {};
  109 +
  110 + files = files instanceof Object ? files : {
  111 + '': files
  112 + };
  113 +
  114 + for (var target in files) {
  115 +
  116 + map[target] = files[target];
  117 + }
  118 + return map;
91 119 });
92   -};
  120 +};
59 test/grunt-rsync_test.js
... ... @@ -1,4 +1,5 @@
1   -var grunt = require('grunt');
  1 +var grunt = require('grunt'),
  2 + rsync = require('../tasks/rsync');
2 3
3 4 /*
4 5 ======== A Handy Little Nodeunit Reference ========
@@ -23,10 +24,64 @@ var grunt = require('grunt');
23 24 exports.rsync = {
24 25 'one': function (test) {
25 26 'use strict';
26   -
  27 +
27 28 test.expect(1);
28 29 // tests here
29 30 test.equal(1, 1);
30 31 test.done();
  32 + },
  33 + 'Helper#createFileMap with one flat file <string> (no map)': function (test) {
  34 + 'use strict';
  35 + test.expect(1);
  36 +
  37 + var files = 'a/b/c';
  38 + var fileMap = grunt.helper('createFileMap', files);
  39 +
  40 + test.deepEqual(fileMap, {
  41 + '': 'a/b/c'
  42 + });
  43 + test.done();
  44 + },
  45 + 'Helper#createFileMap-identity with one element map <string:string>': function (test) {
  46 + 'use strict';
  47 + test.expect(1);
  48 +
  49 + var files = {
  50 + 'cde/f': 'a/b/c'
  51 + };
  52 + var fileMap = grunt.helper('createFileMap', files);
  53 +
  54 + test.deepEqual(fileMap, {
  55 + 'cde/f': 'a/b/c'
  56 + });
  57 + test.done();
  58 + },
  59 + 'Helper#createFileMap-identity with one element map <string:[string]>': function (test) {
  60 + 'use strict';
  61 + test.expect(1);
  62 +
  63 + var files = {
  64 + 'cde/f': ['a/b/c', 'e/**/*.txt']
  65 + };
  66 + var fileMap = grunt.helper('createFileMap', files);
  67 +
  68 + test.deepEqual(fileMap, {
  69 + 'cde/f': ['a/b/c', 'e/**/*.txt']
  70 + });
  71 + test.done();
  72 + },
  73 + 'Helper#createFileMap-identity with multiple element map <string:[string]> | <string:string>': function (test) {
  74 + 'use strict';
  75 + test.expect(1);
  76 +
  77 + var files = {
  78 + 'cde/f': ['a/b/c', 'e/**/*.txt'],
  79 + 'ddd/': 'e/f',
  80 + 'rrr/': ['hh/*.txt']
  81 + };
  82 + var fileMap = grunt.helper('createFileMap', files);
  83 +
  84 + test.deepEqual(fileMap, files);
  85 + test.done();
31 86 }
32 87 };
1  test/test-files/ddd/xyz.txt
... ... @@ -0,0 +1 @@
  1 +xyz
1  test/test-files/one.txt
... ... @@ -0,0 +1 @@
  1 +one
1  test/test-files/two.txt
... ... @@ -0,0 +1 @@
  1 +two

0 comments on commit 5494702

Please sign in to comment.
Something went wrong with that request. Please try again.