1 | | /* jshint node: true */ |
2 | 1 | 'use strict'; |
3 | 1 | var CoreObject = require('core-object'); |
4 | 1 | var Promise = require('ember-cli/lib/ext/promise'); |
5 | 1 | var SilentError = require('ember-cli/lib/errors/silent'); |
6 | 1 | var ssh2 = require('ssh2'); |
7 | | |
8 | 1 | module.exports = CoreObject.extend({ |
9 | | init: function() { |
10 | 8 | CoreObject.prototype.init.apply(this, arguments); |
11 | 8 | if (!this.config) { |
12 | 0 | return Promise.reject(new SilentError('You must supply a config')); |
13 | | } |
14 | | |
15 | 8 | this.client = new ssh2.Client(); |
16 | | }, |
17 | | |
18 | | activate: function(revision) { |
19 | 2 | return this._getFileList() |
20 | | .then(this._excludeCurrentRevisionFile.bind(this)) |
21 | | .then(this._getRevisions.bind(this)) |
22 | | .then(this._activateRevision.bind(this, revision)) |
23 | | .then(this._printSuccessMessage.bind(this, 'Revision activated: ' + revision)); |
24 | | }, |
25 | | |
26 | | list: function() { |
27 | 4 | return this._list() |
28 | | .then(this._printRevisions.bind(this)); |
29 | | }, |
30 | | |
31 | | upload: function(buffer) { |
32 | 2 | var key = this.taggingAdapter.createTag(); |
33 | 2 | return this._uploadIfMissing(buffer, key); |
34 | | }, |
35 | | |
36 | | _list: function() { |
37 | 6 | return this._getFileList() |
38 | | .then(this._sortFileList.bind(this)) |
39 | | .then(this._excludeCurrentRevisionFile.bind(this)) |
40 | | .then(this._getRevisions.bind(this)); |
41 | | }, |
42 | | |
43 | | _getFileList: function() { |
44 | 8 | var conn = this.client; |
45 | 8 | var config = this.config; |
46 | 8 | return new Promise(function (resolve, reject) { |
47 | 8 | conn.on('ready', function () { |
48 | 10 | conn.sftp(function(err, sftp) { |
49 | 10 | if (err) { |
50 | 0 | throw err; |
51 | | } |
52 | 10 | sftp.readdir(config.remoteDir, function(err, list) { |
53 | 10 | if (err) { |
54 | 0 | reject(err); |
55 | | } else { |
56 | 10 | conn.end(); |
57 | 10 | resolve(list); |
58 | | } |
59 | | }); |
60 | | }); |
61 | | }).on('error', function (error) { |
62 | 0 | reject(error); |
63 | | }).connect({ |
64 | | host: config.host, |
65 | | username: config.username, |
66 | | privateKey: require('fs').readFileSync(config.privateKeyFile), |
67 | | }); |
68 | | }); |
69 | | }, |
70 | | |
71 | | _sortFileList: function(fileList) { |
72 | 6 | return fileList.sort(function(a, b) { |
73 | 3 | return b.attrs.mtime - a.attrs.mtime; |
74 | | }); |
75 | | }, |
76 | | |
77 | | _getRevisions: function(files) { |
78 | 8 | return files.map(function(file) { |
79 | 9 | return file.filename.substring(0, (file.filename.length - 5)); |
80 | | }); |
81 | | }, |
82 | | |
83 | | _excludeCurrentRevisionFile: function(data) { |
84 | 8 | return data.filter(function (file) { |
85 | 10 | return file.filename !== 'index.html'; |
86 | | }); |
87 | | }, |
88 | | |
89 | | _activateRevision: function (targetRevision, revisions) { |
90 | 2 | if (revisions.indexOf(targetRevision) > -1) { |
91 | 1 | var conn = this.client; |
92 | 1 | var config = this.config; |
93 | 1 | var revisionFile = config.remoteDir + targetRevision + '.html'; |
94 | 1 | var indexFile = config.remoteDir + 'index.html'; |
95 | 1 | return new Promise(function (resolve, reject) { |
96 | 1 | conn.on('ready', function () { |
97 | 1 | conn.sftp(function(err, sftp) { |
98 | 1 | if (err) { |
99 | 0 | throw err; |
100 | | } |
101 | 1 | sftp.unlink(indexFile, function (err) { |
102 | 1 | if (err) { |
103 | 0 | throw err; |
104 | | } |
105 | 1 | sftp.symlink(revisionFile, indexFile, function(err) { |
106 | 1 | if (err) { |
107 | 0 | reject(err); |
108 | | } else { |
109 | 1 | conn.end(); |
110 | 1 | resolve(); |
111 | | } |
112 | | }); |
113 | | }); |
114 | | }); |
115 | | }).on('error', function (error) { |
116 | 0 | reject(error); |
117 | | }).connect({ |
118 | | host: config.host, |
119 | | username: config.username, |
120 | | privateKey: require('fs').readFileSync(config.privateKeyFile), |
121 | | }); |
122 | | }); |
123 | | } else { |
124 | 1 | return this._printErrorMessage("Revision doesn't exist"); |
125 | | } |
126 | | }, |
127 | | |
128 | | _uploadIfMissing: function(value, key) { |
129 | 2 | var conn = this.client; |
130 | 2 | var config = this.config; |
131 | 2 | return new Promise(function(resolve, reject) { |
132 | 2 | this._list() |
133 | | .then(function(revisions) { |
134 | 2 | if (revisions.indexOf(key) < 0) { |
135 | 1 | conn.on('ready', function () { |
136 | 1 | conn.sftp(function(err, sftp) { |
137 | 1 | if (err) { |
138 | 0 | throw err; |
139 | | } |
140 | 1 | var writeStream = sftp.createWriteStream(config.remoteDir + key + '.html'); |
141 | 1 | writeStream.on('error', function(err) { |
142 | 0 | reject(err); |
143 | | }); |
144 | 1 | writeStream.on('finish', function() { |
145 | 1 | resolve(); |
146 | | }); |
147 | 1 | writeStream.write(value); |
148 | | }); |
149 | | }).on('error', function (error) { |
150 | 0 | reject(error); |
151 | | }).connect({ |
152 | | host: config.host, |
153 | | username: config.username, |
154 | | privateKey: require('fs').readFileSync(config.privateKeyFile), |
155 | | }); |
156 | | } else { |
157 | 1 | reject(new SilentError('Revision already uploaded.')); |
158 | | } |
159 | | }.bind(this)) |
160 | | .catch(function (error) { |
161 | 0 | reject(error); |
162 | | }); |
163 | | }.bind(this)); |
164 | | }, |
165 | | |
166 | | _printRevisions: function(list) { |
167 | 4 | var header = 'Found the following revisions:'; |
168 | 4 | var revisionsList = list.join('\n'); |
169 | 4 | return this._printSuccessMessage('\n' + header + '\n\n' + revisionsList + '\n'); |
170 | | }, |
171 | | |
172 | | _printSuccessMessage: function (message) { |
173 | 5 | return this.ui.writeLine(message); |
174 | | }, |
175 | | |
176 | | _printErrorMessage: function (message) { |
177 | 1 | return Promise.reject(new SilentError(message)); |
178 | | }, |
179 | | |
180 | | }); |
181 | | |