UNPKG

5.85 kBJavaScriptView Raw
1var $, M, _, kleur, path;
2
3$ = {};
4
5$.info = require('../dist/info');
6
7$.formatArgument = require('../dist/formatArgument');
8
9$.parseString = require('../dist/parseString');
10
11$.i = require('../dist/i');
12
13$.wrapList = require('../dist/wrapList');
14
15$.normalizePathToArray = require('../dist/normalizePathToArray');
16
17$.type = require('../dist/type');
18
19$.stat_ = require('../dist/stat_');
20
21$.walk_ = require('../dist/walk_');
22
23_ = {};
24
25_.trim = require('lodash/trim');
26
27_.clone = require('lodash/clone');
28
29// https://github.com/mscdex/ssh2
30kleur = require('kleur');
31
32path = require('path');
33
34M = class M {
35 /*
36 connect_(option)
37 disconnect_()
38 exec_(cmd, [option])
39 info(chunk)
40 mkdir_(source)
41 remove_(source)
42 uploadDir_(sftp, source, target)
43 uploadFile_(sftp, source, target)
44 upload_(source, target, [option])
45 */
46 async connect_(option) {
47 await new Promise((resolve) => {
48 var Client, conn, infoServer;
49 ({Client} = require('ssh2'));
50 conn = new Client();
51 infoServer = `${option.username}@${option.host}`;
52 conn.on('end', function() {
53 return $.info('ssh', `disconnected from '${infoServer}'`);
54 }).on('error', function(err) {
55 throw new Error(err);
56 }).on('ready', function() {
57 $.info('ssh', `connected to '${infoServer}'`);
58 return resolve();
59 }).connect(option);
60 return this.storage = {conn, option};
61 });
62 return this;
63 }
64
65 async disconnect_() {
66 await new Promise((resolve) => {
67 var conn;
68 ({conn} = this.storage);
69 return conn.on('end', function() {
70 return resolve();
71 }).end();
72 });
73 return this;
74 }
75
76 async exec_(cmd, option = {}) {
77 await new Promise((resolve) => {
78 var conn;
79 ({conn} = this.storage);
80 cmd = $.formatArgument(cmd);
81 cmd = cmd.join(' && ');
82 $.info('ssh', kleur.blue(cmd));
83 return conn.exec(cmd, (err, stream) => {
84 if (err) {
85 throw new Error(err);
86 }
87 stream.on('end', function() {
88 return resolve();
89 });
90 stream.stderr.on('data', (chunk) => {
91 if (option.ignoreError) {
92 return this.info(chunk);
93 }
94 throw new Error($.parseString(chunk));
95 });
96 return stream.stdout.on('data', (chunk) => {
97 return this.info(chunk);
98 });
99 });
100 });
101 return this;
102 }
103
104 info(chunk) {
105 var string;
106 string = _.trim($.parseString(chunk));
107 if (!string.length) {
108 return;
109 }
110 string = string.replace(/\r/g, '\n').replace(/\n{2,}/g, '');
111 return $.i(string);
112 }
113
114 mkdir_(source) {
115 var cmd, src;
116 source = $.formatArgument(source);
117 cmd = ((function() {
118 var i, len, results;
119 results = [];
120 for (i = 0, len = source.length; i < len; i++) {
121 src = source[i];
122 results.push(`mkdir -p ${src}`);
123 }
124 return results;
125 })()).join('; ');
126 $.info().silence_(async() => {
127 return (await this.exec_(cmd));
128 });
129 $.info('ssh', `created ${$.wrapList(source)}`);
130 return this;
131 }
132
133 remove_(source) {
134 var cmd, src;
135 source = $.formatArgument(source);
136 cmd = ((function() {
137 var i, len, results;
138 results = [];
139 for (i = 0, len = source.length; i < len; i++) {
140 src = source[i];
141 results.push(`rm -fr ${src}`);
142 }
143 return results;
144 })()).join('; ');
145 $.info().silence_(async() => {
146 return (await this.exec_(cmd));
147 });
148 $.info('ssh', `removed ${$.wrapList(source)}`);
149 return this;
150 }
151
152 async upload_(source, target, option = {}) {
153 await new Promise((resolve) => {
154 var conn;
155 ({conn} = this.storage);
156 source = $.normalizePathToArray(source);
157 option = (function() {
158 switch ($.type(option)) {
159 case 'object':
160 return _.clone(option);
161 case 'string':
162 return {
163 filename: option
164 };
165 default:
166 throw new Error('ssh/error: invalid type');
167 }
168 })();
169 return conn.sftp(async(err, sftp) => {
170 var filename, i, len, src, stat;
171 if (err) {
172 throw new Error(err);
173 }
174 for (i = 0, len = source.length; i < len; i++) {
175 src = source[i];
176 stat = (await $.stat_(src));
177 filename = option.filename || path.basename(src);
178 if (stat.isDirectory()) {
179 await this.uploadDir_(sftp, src, `${target}/${filename}`);
180 } else if (stat.isFile()) {
181 await this.mkdir_(target);
182 await this.uploadFile_(sftp, src, `${target}/${filename}`);
183 }
184 }
185 sftp.end();
186 return resolve();
187 });
188 });
189 return this;
190 }
191
192 async uploadDir_(sftp, source, target) {
193 await new Promise(async(resolve) => {
194 var i, len, listSource, relativeTarget, src, stat;
195 listSource = [];
196 await $.walk_(source, function(item) {
197 return listSource.push(item.path);
198 });
199 for (i = 0, len = listSource.length; i < len; i++) {
200 src = listSource[i];
201 stat = (await $.stat_(src));
202 relativeTarget = path.normalize(`${target}/${path.relative(source, src)}`);
203 if (stat.isDirectory()) {
204 await this.mkdir_(relativeTarget);
205 } else if (stat.isFile()) {
206 await this.uploadFile_(sftp, src, relativeTarget);
207 }
208 }
209 return resolve();
210 });
211 return this;
212 }
213
214 async uploadFile_(sftp, source, target) {
215 await new Promise(function(resolve) {
216 return sftp.fastPut(source, target, function(err) {
217 if (err) {
218 throw new Error(err);
219 }
220 $.info('ssh', `uploaded '${source}' to '${target}'`);
221 return resolve();
222 });
223 });
224 return this;
225 }
226
227};
228
229module.exports = function() {
230 return new M();
231};