1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188 | 2
2
2
2
2
2
2
1
2
1
2
5
5
5
5
1
1
1
5
4
1
2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
1
1
1
1
1
1
1
1
1
1
2
2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
2
2
2
1
2
1
2
2
2 | var cli = require('bagofcli');
var fsx = require('fs.extra');
var FtpDeploy = require('ftp-deploy');
var p = require('path');
var rsyncwrapper = require('rsyncwrapper');
var scp2 = require('scp2');
var util = require('util');
/**
* Class Sendman
*/
function Sendman() {
}
/**
* Create a sample .sendman.json setup file in current working directory.
*
* @param {Function} cb: standard cb(err, result) callback
*/
Sendman.prototype.init = function (cb) {
fsx.copy(p.join(__dirname, '../examples/.sendman.json'), '.sendman.json', cb);
};
/**
* Send files with properties in a configuration file.
*
* @param {String} file: configuration file, default: .sendman.json
* @param {Function} cb: standard cb(err, result) callback
*/
Sendman.prototype.send = function (file, cb) {
const DEFAULT_PORT = 21;
const MAX_UPLOADS = 10;
var opts = JSON.parse(cli.lookupFile(file));
// merge sub-configuration file
if (opts.include) {
var moreOpts = JSON.parse(cli.lookupFile(opts.include));
Object.keys(moreOpts).forEach(function (key) {
opts[key] = moreOpts[key];
});
}
if (['ftp', 'scp', 'rsync'].indexOf(opts.protocol) !== -1) {
this['_' + opts.protocol](opts, cb);
} else {
cb(new Error('Unsupported protocol %s', opts.protocol));
}
};
/**
* Send files under a local path to a remote path via FTP.
*
* @param {Object} opts: optional
* - host: hostname
* - port: port number, default: 21
* - username: username
* - password: password
* - local: local path, which files will be deployed
* - remote: remote path where to send the local files to
* @param {Function} cb: standard cb(err, result) callback
*/
Sendman.prototype._ftp = function (opts, cb) {
const DEFAULT_PORT = 21;
const DEFAULT_PARALLEL = 10;
// add alias properties
opts.localRoot = opts.local;
opts.remoteRoot = opts.remote;
// set defaults
opts.port = opts.port || DEFAULT_PORT;
opts.parallelUploads = opts.parallel || DEFAULT_PARALLEL;
// remove temporary properties
delete opts.protocol;
delete opts.include;
delete opts.local;
delete opts.remote;
// send file via FTP
var ftpDeploy = new FtpDeploy();
ftpDeploy.on('uploaded', function(data) {
console.log('%s (%d/%d)', p.join(data.relativePath, data.filename), data.transferredFileCount, data.totalFileCount);
});
ftpDeploy.deploy(opts, cb);
};
/**
* Send files under a local path to a remote path via SCP.
*
* @param {Object} opts: optional
* - host: hostname
* - port: port number, default: 22
* - username: username
* - password: password
* - local: local path, which files will be deployed
* - remote: remote path where to send the local files to
* @param {Function} cb: standard cb(err, result) callback
*/
Sendman.prototype._scp = function (opts, cb) {
const DEFAULT_PORT = 22;
// add alias properties
opts.localRoot = opts.local;
opts.remoteRoot = opts.remote;
// set defaults
opts.port = opts.port || DEFAULT_PORT;
// remove temporary properties
delete opts.protocol;
delete opts.include;
delete opts.local;
delete opts.remote;
// send file via SCP
var remoteUrl = util.format('%s:%s@%s:%s', opts.username, opts.password, opts.host, opts.remoteRoot);
scp2.scp(opts.localRoot, remoteUrl, cb);
};
/**
* Send files under a local path to a local or remote path via rsync.
* Option source or destination can either be a /path/to/file or <username>@<host>:/path/to/file
*
* @param {Object} opts: optional
* - host: hostname
* - username: username
* - password: password
* - local: local path, which files will be deployed
* - remote: remote path where to send the local files to
* - source: local or remote path of source file/directory to be deployed
* - destination: local or remote path of destination file/directory to send to
* @param {Function} cb: standard cb(err, result) callback
*/
Sendman.prototype._rsync = function (opts, cb) {
// use remote URL construction, handy for easy switching from SCP to rsync protocol
if (opts.local) {
opts.src = opts.local;
opts.dest = util.format('%s:%s@%s:%s', opts.username, opts.password, opts.host, opts.remote);
// remove temporary properties
delete opts.protocol;
delete opts.include;
delete opts.local;
delete opts.remote;
delete opts.host;
delete opts.username;
delete opts.password;
// use freeform source and destination locations
} else {
opts.src = opts.source;
opts.dest = opts.destination;
// remove temporary properties
delete opts.protocol;
delete opts.source;
delete opts.destination;
}
opts.recursive = true;
rsyncwrapper.rsync(opts, function (err, stdout, stderr, cmd) {
console.log(cmd);
if (stdout) {
console.log(stdout);
}
if (stderr) {
console.error(stderr);
}
var result = {
stdout: stdout,
stderr: stderr,
cmd: cmd
};
cb(err, result);
});
};
module.exports = Sendman; |