124 lines
3.5 KiB
JavaScript
124 lines
3.5 KiB
JavaScript
import { EventEmitter as Emitter } from 'events'
|
|
import stream from 'stream'
|
|
import Watcher from './watcher'
|
|
import Ssh from './ssh'
|
|
import Sync from './lib/sync'
|
|
|
|
const devNull = new stream.Writable()
|
|
devNull._write = () => null
|
|
|
|
class RemoteCode {
|
|
constructor(opts = {}) {
|
|
// Set defaults
|
|
// a id emitted with every event emit that can identify which remote code emitted
|
|
this.id = opts.id
|
|
this.watch = opts.watch || false
|
|
this.options.ssh.keepaliveInterval = opts.ssh.keepaliveInterval || 500
|
|
this.options.ssh.readyTimeout = opts.ssh.readyTimeout || 2000
|
|
this.options.ssh.port = opts.ssh.port || 22
|
|
this.options.source = opts.source || '.'
|
|
this.options.install = opts.install || 'yarn'
|
|
this.options.install = opts.registry ? `${this.options.install} --registry ${opts.registry}` : this.options.install
|
|
this.options.start = opts.start || 'nodemon .'
|
|
if (!(opts.ssh.keyfilePath || opts.ssh.password)) {
|
|
this.options.ssh.agent = process.env[opts.ssh.agent] || process.env.SSH_AUTH_SOCK || process.env.SSH_AGENT_SOCK
|
|
if (!this.options.ssh.agent) {
|
|
return new Error('no ssh authentification method provided')
|
|
}
|
|
}
|
|
this.ssh = new Ssh()
|
|
this.verbose = opts.verbose || false
|
|
this.stdout = opts.stdout instanceof stream.Writable ? opts.stdout : new stream.Writable()
|
|
this.stderr = opts.stderr instanceof stream.Writable ? opts.stderr : new stream.Writable()
|
|
this.watcher = new Watcher(this.options)
|
|
this.sync = new Sync(this.options)
|
|
.addStdOutStream(this.stdout)
|
|
.addStdErrStream(this.stderr)
|
|
}
|
|
|
|
|
|
|
|
_getStdOut() {
|
|
if (this.verbose) {
|
|
return this.stdout
|
|
}
|
|
return devNull
|
|
}
|
|
|
|
_getStdErr() {
|
|
if (this.verbose) {
|
|
return this.stderr
|
|
}
|
|
return devNull
|
|
}
|
|
|
|
sync() {
|
|
this.emit('sync',{})
|
|
return this.sync.execute()
|
|
}
|
|
|
|
watch() {
|
|
this.watcher.start()
|
|
const watchEmitter = this.watcher.getEventEmitter()
|
|
watchEmitter.on('sync', () => {
|
|
this.syncCode()
|
|
})
|
|
watchEmitter.on('install', () => {
|
|
return this.install()
|
|
.then(() => {
|
|
this.ssh.liveReload.send('rs')
|
|
})
|
|
})
|
|
return this.emitter
|
|
}
|
|
|
|
async init() {
|
|
this.emitter.emit('start')
|
|
const sshSettings = this.options.ssh
|
|
return Promise.all([this.syncCode(), this.watch()])
|
|
.then(() => this.install())
|
|
.then(() => this.ssh.liveReload.connect(sshSettings))
|
|
.then(() => {
|
|
this.emitter.emit('nodemon', 'start')
|
|
this.ssh.liveReload.send(`cd ${this.options.target} && ${this.options.start}`)
|
|
})
|
|
.catch(this._abort.bind(this))
|
|
}
|
|
|
|
// execute a single command and then resolve
|
|
execute(cmd, stdout, stderr) {
|
|
console.log('remote codes exec', cmd)
|
|
this.emitter.emit('exec', cmd)
|
|
const ssh = new Ssh()
|
|
const result = ssh.exec(this.options.ssh, cmd, stdout, stderr)
|
|
return result
|
|
}
|
|
|
|
async install() {
|
|
this.emit('install', 'triggered')
|
|
if (!this.installInProgress) {
|
|
this.emitter.emit('install', 'started')
|
|
console.log('calling execute from install')
|
|
return this.execute(`cd ${this.options.target} && ${this.options.install}`, this._getStdOut(), this._getStdErr())
|
|
.then(res => {
|
|
this.emit('install', 'done', res)
|
|
this.installInProgress = false
|
|
return res
|
|
})
|
|
}
|
|
return Promise.resolve()
|
|
}
|
|
|
|
close() {
|
|
this.emitter.emit('close')
|
|
return Promise.all([this.watcher.close(),
|
|
this.ssh.liveReload.close()])
|
|
}
|
|
|
|
_abort(err) {
|
|
this.emitter.emit('error', err)
|
|
}
|
|
}
|
|
|
|
export default RemoteCode
|