ftp-deploy
Advanced tools
Comparing version 1.1.0 to 1.2.0
@@ -1,36 +0,47 @@ | ||
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'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const util = require('util'); | ||
const events = require('events'); | ||
const Ftp = require('jsftp'); | ||
const async = require('async'); | ||
const minimatch = require('minimatch'); | ||
const read = require('read'); | ||
// A utility function to remove lodash/underscore dependency | ||
// Checks an obj for a specified key | ||
function has (obj, key) { | ||
function has(obj, key) { | ||
return Object.prototype.hasOwnProperty.call(obj, key); | ||
} | ||
var FtpDeployer = function () { | ||
// the constructor for the super class. | ||
const FtpDeployer = function () { | ||
// The constructor for the super class. | ||
events.EventEmitter.call(this); | ||
var thisDeployer = this; | ||
const 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; | ||
let transferredFileCount = 0; | ||
let ftp; | ||
let localRoot; | ||
let remoteRoot; | ||
const partialDirectories = []; // Holds list of directories to check & create (excluding local root path) | ||
const partialFilePaths = []; // Holds list of partial file paths to upload | ||
// var parallelUploads = 1; // NOTE: this can be added in when sftp is supported | ||
let exclude = []; | ||
let include = []; | ||
let continueOnError = false; | ||
function canIncludeFile(filePath) { | ||
let i; | ||
if (include.length > 0) { | ||
for (i = 0; i < include.length; i++) { | ||
if (minimatch(filePath, include[i], {matchBase: true})) { | ||
return true; | ||
} | ||
} | ||
// Fallthrough to exclude list | ||
} | ||
if (exclude.length > 0) { | ||
for(var i = 0; i < exclude.length; i++) { | ||
for (i = 0; i < exclude.length; i++) { | ||
if (minimatch(filePath, exclude[i], {matchBase: true})) { | ||
@@ -46,8 +57,7 @@ return false; | ||
function dirParseSync(startDir, result) { | ||
var files; | ||
var i; | ||
var tmpPath; | ||
var currFile; | ||
let i; | ||
let tmpPath; | ||
let currFile; | ||
// initialize the `result` object if it is the first iteration | ||
// Initialize the `result` object if it is the first iteration | ||
if (result === undefined) { | ||
@@ -58,3 +68,3 @@ result = {}; | ||
// check if `startDir` is a valid location | ||
// Check if `startDir` is a valid location | ||
if (!fs.existsSync(startDir)) { | ||
@@ -64,4 +74,4 @@ console.error(startDir + 'is not an existing location'); | ||
// iterate throught the contents of the `startDir` location of the current iteration | ||
files = fs.readdirSync(startDir); | ||
// Iterate throught the contents of the `startDir` location of the current iteration | ||
const files = fs.readdirSync(startDir); | ||
for (i = 0; i < files.length; i++) { | ||
@@ -73,3 +83,3 @@ currFile = path.join(startDir, files[i]); | ||
// check exclude rules | ||
// Check exclude rules | ||
if (canIncludeFile(tmpPath)) { | ||
@@ -84,11 +94,11 @@ if (!has(result, tmpPath)) { | ||
tmpPath = path.relative(localRoot, startDir); | ||
if (!tmpPath.length) { | ||
if (tmpPath.length === 0) { | ||
tmpPath = path.sep; | ||
} | ||
// check exclude rules | ||
var partialFilePath = path.join(tmpPath, files[i]); | ||
// Check exclude rules | ||
const partialFilePath = path.join(tmpPath, files[i]); | ||
if (canIncludeFile(partialFilePath)) { | ||
result[tmpPath].push(files[i]); | ||
partialFilePaths.push(partialFilePath); | ||
partialFilePaths.push(partialFilePath); | ||
} | ||
@@ -103,22 +113,22 @@ } | ||
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 | ||
}; | ||
let remoteFilePath = remoteRoot + '/' + partialFilePath; | ||
remoteFilePath = remoteFilePath.replace(/\\/g, '/'); | ||
const fullLocalPath = path.join(localRoot, partialFilePath); | ||
const emitData = { | ||
totalFileCount: partialFilePaths.length, | ||
transferredFileCount, | ||
percentComplete: Math.round((transferredFileCount / partialFilePaths.length) * 100), | ||
filename: partialFilePath | ||
}; | ||
thisDeployer.emit('uploading', emitData); | ||
ftp.put(fullLocalPath, remoteFilePath, function (err) { | ||
ftp.put(fullLocalPath, remoteFilePath, 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) { | ||
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(); | ||
@@ -136,89 +146,93 @@ } else { | ||
} | ||
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(); | ||
} | ||
}); | ||
} | ||
function ftpMakeDirectoriesIfNeeded(cb) { | ||
async.eachSeries(partialDirectories, ftpMakeRemoteDirectoryIfNeeded, 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 | ||
let 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, err => { | ||
if (err) { | ||
ftp.raw.mkd(fullRemoteDirectory, 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); | ||
} | ||
}; | ||
// Prompt for password if none was given | ||
if (config.password) { | ||
configComplete(config, cb); | ||
} else { | ||
read({prompt: 'Password for ' + config.username + '@' + config.host + ' (ENTER for none): ', default: '', silent: true}, (err, res) => { | ||
if (err) { | ||
return cb(err); | ||
} | ||
config.password = res; | ||
configComplete(config, cb); | ||
}); | ||
} | ||
}; | ||
function configComplete(config, cb) { | ||
function configComplete(config, cb) { | ||
// Init | ||
ftp = new Ftp({ | ||
host: config.host, | ||
port: config.port | ||
}); | ||
// Init | ||
ftp = new Ftp({ | ||
host: config.host, | ||
port: config.port | ||
}); | ||
localRoot = config.localRoot; | ||
remoteRoot = config.remoteRoot; | ||
if (has(config, 'continueOnError')) { | ||
continueOnError = config.continueOnError; | ||
} | ||
exclude = config.exclude || exclude; | ||
include = config.include || include; | ||
localRoot = config.localRoot; | ||
remoteRoot = config.remoteRoot; | ||
if (has(config, 'continueOnError')) continueOnError = config.continueOnError; | ||
exclude = config.exclude || exclude; | ||
ftp.useList = true; | ||
dirParseSync(localRoot); | ||
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 { | ||
async.eachSeries(partialFilePaths, ftpPut, function (err) { | ||
if (err) { | ||
cb(err); | ||
} else { | ||
ftp.raw.quit(function (err) { | ||
cb(err); | ||
}); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
// Authentication and main processing of files | ||
ftp.auth(config.username, config.password, err => { | ||
if (err) { | ||
cb(err); | ||
} else { | ||
ftpMakeDirectoriesIfNeeded(err => { | ||
if (err) { | ||
// If there was an error creating a remote directory we can't continue to upload files | ||
cb(err); | ||
} else { | ||
async.eachSeries(partialFilePaths, ftpPut, err => { | ||
if (err) { | ||
cb(err); | ||
} else { | ||
ftp.raw.quit(err => { | ||
cb(err); | ||
}); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
}; | ||
@@ -228,2 +242,2 @@ | ||
module.exports = FtpDeployer; | ||
module.exports = FtpDeployer; |
{ | ||
"name": "ftp-deploy", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"author": "Rick Bergfalk <rick.bergfalk@gmail.com> (http://rickbergfalk.com/)", | ||
@@ -23,2 +23,5 @@ "description": "Ftp a folder from your local disk to an ftp destination. Does not delete from destination directory. Derived from grunt-ftp-deploy", | ||
}, | ||
"engines": { | ||
"node": ">=4" | ||
}, | ||
"contributors": [ | ||
@@ -35,5 +38,10 @@ { | ||
"scripts": { | ||
"lint": "xo", | ||
"lint-fix": "xo --fix", | ||
"test": "node test/test.js" | ||
}, | ||
"main": "ftp-deploy" | ||
"main": "ftp-deploy", | ||
"devDependencies": { | ||
"xo": "^0.18.1" | ||
} | ||
} |
@@ -9,3 +9,6 @@ # ftp-deploy | ||
## Currently Unmaintained | ||
If you would like to take ownership of this module on npm let me know. | ||
## Usage | ||
@@ -26,3 +29,4 @@ | ||
remoteRoot: "/public_html/remote-folder/", | ||
exclude: ['.git', '.idea', 'tmp/*'] | ||
include: ['build/version.txt'], | ||
exclude: ['.git', '.idea', 'tmp/*', 'build/*'] | ||
} | ||
@@ -29,0 +33,0 @@ |
@@ -1,27 +0,32 @@ | ||
var FtpDeploy = require('../ftp-deploy.js'); | ||
var ftpDeploy = new FtpDeploy(); | ||
const path = require('path'); | ||
const FtpDeploy = require('../ftp-deploy.js'); | ||
var config = { | ||
username: "rickbergfalk", | ||
password: "", // optional, prompted if none given | ||
host: "localhost", | ||
port: 21, | ||
localRoot: __dirname + "/test-root", | ||
remoteRoot: "/Users/rickbergfalk/Public/", | ||
exclude: ['.git', '.idea', 'tmp/*'] | ||
const ftpDeploy = new FtpDeploy(); | ||
const config = { | ||
username: 'rickbergfalk', | ||
password: '', // Optional, prompted if none given | ||
host: 'localhost', | ||
port: 21, | ||
localRoot: path.join(__dirname, 'test-root'), | ||
remoteRoot: '/Users/rickbergfalk/Public/', | ||
exclude: ['.git', '.idea', 'tmp/*'] | ||
}; | ||
ftpDeploy.on('uploaded', function (data) { | ||
console.log('uploaded:'); | ||
console.log(data); | ||
ftpDeploy.on('uploaded', data => { | ||
console.log('uploaded:'); | ||
console.log(data); | ||
}); | ||
ftpDeploy.on('uploading', function (data) { | ||
console.log('uploading'); | ||
console.log(data); | ||
ftpDeploy.on('uploading', data => { | ||
console.log('uploading'); | ||
console.log(data); | ||
}); | ||
ftpDeploy.deploy(config, function(err) { | ||
if (err) console.log(err); | ||
else console.log('finished'); | ||
}); | ||
ftpDeploy.deploy(config, err => { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
console.log('finished'); | ||
} | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
13
234
80
14021
1