UNPKG

wzt-plugin-shifting

Version:

A simple CLI for publish your projects.

134 lines (124 loc) 3.82 kB
const fs = require('fs') const os = require('os') const path = require('path') const is = require('is') const ProgressBar = require('progress') const createHash = require('crypto').createHash const md5 = input => { return createHash('md5') .update(input) .digest('hex') } const chalk = require('chalk') const Client = require('scp2').Client const logger = require('./index.js').logger module.exports = function sftp(module, env, next) { let isObject = is.object, isString = is.string, isEmpty = is.empty, isFn = is.fn, isUndefined = is.undefined let localLogger = (local, type) => (msg, end = false, cb = next) => logger[type](msg, local, end, cb) let error = localLogger('sftp', 'error') let warning = localLogger('sftp', 'warning') let { localTarFileDir, _compressHash, tarFilename, remoteTarFileDir, ssh } = module if (isUndefined(localTarFileDir)) { return error( `Publish environment '${env}' option 'localTarFileDir' is not found` ) } if (isUndefined(tarFilename)) { return error( `Publish environment '${env}' option 'tarFilename' is not found` ) } if (isUndefined(ssh)) { return error(`Publish environment '${env}' option 'ssh' is not found`) } if (!isString(localTarFileDir)) { return error( `Publish environment '${env}' option 'localTarFileDir' must be a string` ) } if (!isString(tarFilename)) { return error( `Publish environment '${env}' option 'tarFilename' must be a string` ) } if (remoteTarFileDir && !isString(remoteTarFileDir)) { return error( `Publish environment '${env}' option 'remoteTarFileDir' must be a string` ) } remoteTarFileDir = remoteTarFileDir ? path.posix.join(remoteTarFileDir, '.') : '/tmp' if ( !/^(\/[^\/\s]+){2,}$/.test(remoteTarFileDir) && remoteTarFileDir !== '/tmp' ) { return error( `Publish environment '${env}' option 'remoteTarFileDir' file path is no vaild, the file path must be more than two level directory, and must be absolute path` ) } let _sftpHash = md5( [ssh.host] .concat(_compressHash || localTarFileDir + tarFilename) .concat(remoteTarFileDir) .join('') ).slice(0, 5) module._sftpHash = _sftpHash module.remoteTarFileDir = remoteTarFileDir let localTarpackPath = path.resolve(localTarFileDir, tarFilename) let remoteTarpackPath = path.posix.join(remoteTarFileDir, tarFilename) let hashPromiseName = `_${_sftpHash}HashSftpPromise` let client = new Client(ssh) let p = this[hashPromiseName] ? this[hashPromiseName] : (this[hashPromiseName] = new Promise((resolve, reject) => { if (this._metadata.check) return resolve(null) console.log( `${chalk.blue(localTarpackPath)} => ${chalk.green(remoteTarpackPath)}` ) let bar = new ProgressBar(' Uploading [:bar] :percent :etas', { complete: '=', incomplete: ' ', width: 20, total: 100 }) client.upload(localTarpackPath, remoteTarpackPath, err => { client.close() }) client.on('transfer', (buffer, uploaded, total) => { bar.update(uploaded / total) }) client.on('end', () => { bar.update(1) resolve(null) }) client.on('error', err => { bar.update(1) resolve(err) }) }).catch(next)) p.then(err => { if (err) { error( `Publish environment '${env}' sftp failures, ${err.message}`, false, () => {} ) next(err) } else { logger.success(`env ${env} sftp success`) next(null, 'sftp success') } }) }