UNPKG

tch-command-pack

Version:

* 增加代码的压缩功能,如果是线上则压缩,测试服务器不压缩. #### 0.3.0 * 增加了一个tch pack -t 09284-09295,可以根据两个里程碑打包之间的改动代码 #### 0.1.6 * 增加了一个tch pack -n 功能,只打包非构建的代码,加快打包速度

226 lines (196 loc) 7.82 kB
/** * @desc copy from https://github.com/rickbergfalk/ftp-deploy * @type {exports} */ var fs = require('fs'); var path = require('path'); var util = require('util'); var events = require('events'); var Ftp = require('jsftp'); var async = require('async'); var minimatch = require("minimatch"); var read = require('read'); // A utility function to remove lodash/underscore dependency // Checks an obj for a specified key function has (obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); } var FtpDeployer = function () { // the constructor for the super class. events.EventEmitter.call(this); var thisDeployer = this; var toTransfer; // eventually holds the result of dirParseSync() var transferredFileCount = 0; var ftp; var localRoot; var remoteRoot; var partialDirectories = []; // holds list of directories to check & create (excluding local root path) var partialFilePaths = []; // holds list of partial file paths to upload //var parallelUploads = 1; // NOTE: this can be added in when sftp is supported var exclude = []; var continueOnError = false; function canIncludeFile(filePath) { if (exclude.length > 0) { for(var i = 0; i < exclude.length; i++) { if (minimatch(filePath, exclude[i], {matchBase: true})) { return false; } } } return true; } // A method for parsing the source location and storing the information into a suitably formated object function dirParseSync(startDir, result) { var files; var i; var tmpPath; var currFile; // initialize the `result` object if it is the first iteration if (result === undefined) { result = {}; result[path.sep] = []; } // check if `startDir` is a valid location if (!fs.existsSync(startDir)) { console.error(startDir + 'is not an existing location'); } // iterate throught the contents of the `startDir` location of the current iteration files = fs.readdirSync(startDir); for (i = 0; i < files.length; i++) { currFile = path.join(startDir, files[i]); if (fs.lstatSync(currFile).isDirectory()) { tmpPath = path.relative(localRoot, currFile); // check exclude rules if (canIncludeFile(tmpPath)) { if (!has(result, tmpPath)) { result[tmpPath] = []; partialDirectories.push(tmpPath); } dirParseSync(currFile, result); } } else { tmpPath = path.relative(localRoot, startDir); if (!tmpPath.length) { tmpPath = path.sep; } // check exclude rules var partialFilePath = path.join(tmpPath, files[i]); if (canIncludeFile(partialFilePath)) { result[tmpPath].push(files[i]); partialFilePaths.push(partialFilePath); } } } return result; } // A method for uploading a single file function ftpPut(partialFilePath, cb) { var remoteFilePath = remoteRoot + "/" + partialFilePath; remoteFilePath = remoteFilePath.replace(/\\/g, '/'); var fullLocalPath = path.join(localRoot, partialFilePath); var emitData = { totalFileCount: partialFilePaths.length, transferredFileCount: transferredFileCount, percentComplete: Math.round((transferredFileCount / partialFilePaths.length) * 100), filename: partialFilePath }; thisDeployer.emit('uploading', emitData); ftp.put(fullLocalPath, remoteFilePath, function (err) { if (err) { emitData.err = err; //thisDeployer.emit('error', emitData); // error event from 0.5.x TODO: either expand error events or remove this //thisDeployer.emit('upload-error', emitData); if (continueOnError) { cb(); } else { cb(err); } } else { transferredFileCount++; emitData.transferredFileCount = transferredFileCount; thisDeployer.emit('uploaded', emitData); cb(); } }); } function ftpMakeDirectoriesIfNeeded (cb) { async.eachSeries(partialDirectories, ftpMakeRemoteDirectoryIfNeeded, function (err) { cb(err); }); } // A method for changing the remote working directory and creating one if it doesn't already exist function ftpMakeRemoteDirectoryIfNeeded(partialRemoteDirectory, cb) { // add the remote root, and clean up the slashes var fullRemoteDirectory = remoteRoot + '/' + partialRemoteDirectory.replace(/\\/gi, '/'); // add leading slash if it is missing if (fullRemoteDirectory.charAt(0) !== '/') { fullRemoteDirectory = '/' + fullRemoteDirectory; } // remove double // if present fullRemoteDirectory = fullRemoteDirectory.replace(/\/\//g, "/"); ftp.raw.cwd(fullRemoteDirectory, function(err) { if (err) { ftp.raw.mkd(fullRemoteDirectory, function(err) { if(err) { cb(err); } else { ftpMakeRemoteDirectoryIfNeeded(partialRemoteDirectory, cb); } }); } else { cb(); } }); } this.deploy = function (config, cb) { // Prompt for password if none was given if (!config.password) { read({prompt: 'Password for ' + config.username + '@' + config.host + ' (ENTER for none): ', default: '', silent:true}, function (err, res) { config.password = res; configComplete(config, cb); }); } else { configComplete(config, cb); } }; function configComplete(config, cb) { // Init ftp = new Ftp({ host: config.host, port: config.port }); ftp.setDebugMode = true; localRoot = config.localRoot; remoteRoot = config.remoteRoot; if (has(config, 'continueOnError')) continueOnError = config.continueOnError; exclude = config.exclude || exclude; ftp.useList = true; toTransfer = dirParseSync(localRoot); // Authentication and main processing of files ftp.auth(config.username, config.password, function (err) { if (err) { cb(err); } else { ftpMakeDirectoriesIfNeeded(function (err) { if (err) { // if there was an error creating a remote directory we can't continue to upload files cb(err); } else { var i = 0; ftpPut(partialFilePaths.pop(),function(){ if(partialFilePaths.length > 0){ ftpPut(partialFilePaths.pop(),arguments.callee); }else{ ftp.raw.quit(function(err){ cb(err); }) } }); } }); } }); } }; util.inherits(FtpDeployer, events.EventEmitter); module.exports = FtpDeployer;