84 lines
4.2 KiB
JavaScript
84 lines
4.2 KiB
JavaScript
const path = require('path')
|
|
const Client = require('ftp')
|
|
const filewalker = require('filewalker')
|
|
const chalk = require('chalk')
|
|
const log = console.log;
|
|
|
|
/* FTP functions */
|
|
// create client instance
|
|
const client = new Client()
|
|
// connect to server
|
|
const connect = (options) => new Promise((resolve, reject) => client.on('ready', () => resolve()) && client.connect(options))
|
|
// get list of files/dirs in root directory
|
|
const list = () => new Promise((resolve, reject) => client.list((err, list) => err ? reject(err) : resolve(list)))
|
|
// recursively create a directory structure on the server
|
|
const mkdir = name => new Promise((resolve, reject) => client.mkdir(name, true, err => err ? reject(err) : resolve(name)))
|
|
// recursively remove a directory structure from the server
|
|
const rmdir = name => new Promise((resolve, reject) => client.rmdir(name, true, err => err ? reject(err) : resolve(name)))
|
|
// remove a file from the server
|
|
const remove_file = name => new Promise((resolve, reject) => client.delete(name, err => err ? reject(err) : resolve(name)))
|
|
// transfer a file to the server (binary mode by default)
|
|
const transfer_file = (local, remote) => new Promise((resolve, reject) => client.put(local, remote, err => err ? reject(err) : resolve([local, remote])))
|
|
// close the connection
|
|
const close = () => client.end()
|
|
|
|
/* Path matching functions */
|
|
// find local folders & files that should be transferred
|
|
const find_paths = (basepath, dist_path) => {
|
|
return new Promise((resolve, reject) => {
|
|
let paths = []
|
|
filewalker(path.join(basepath, dist_path))
|
|
.on('file', file => file.search('.htaccess') !== -1 ? false : paths.push([path.join(basepath, dist_path, file), file]))
|
|
.on('done', () => resolve(paths))
|
|
.walk()
|
|
})
|
|
}
|
|
// get a list of directories that need to be created on the server
|
|
const get_dirs_to_create = files => files.map(file => path.dirname(file[1])).filter((item, i, ar) => ar.indexOf(item) === i).filter(item => item !== '.' && item !== '..')
|
|
// get a list of directories that should be deleted on the server
|
|
const get_dirs_to_delete = paths => paths.filter(path => path.type === 'd' && path.name !== '.' && path.name !== '..').sort((a, b) => parseInt(a.name) < parseInt(b.name)).filter((_, idx, arr) => arr.length < 3 ? false : idx >= 2).map(path => path.name)
|
|
|
|
/* Runner */
|
|
module.exports = config => {
|
|
// get config vars
|
|
const root_dir = config.root_dir
|
|
const basepath = config.basepath
|
|
const dist_path = config.dist_path
|
|
const options = config.ftp_options
|
|
// run async deployment
|
|
return new Promise(async (resolve, reject) => {
|
|
try {
|
|
// make a list of files to be transferred to the server
|
|
const files_to_transfer = await find_paths(basepath, dist_path)
|
|
// make a list of subfolders to be created
|
|
const dirs_to_create = get_dirs_to_create(files_to_transfer)
|
|
// connect to the server
|
|
log(' ', chalk.green('>>'), 'Connecting to server')
|
|
await connect(options)
|
|
// fetch the list of existing folders & delete the oldest one and his .htaccess backup
|
|
log(' ', chalk.green('>>'), 'Deleting oldest deployments')
|
|
const existing_folders = await list()
|
|
const folders_to_delete = get_dirs_to_delete(existing_folders)
|
|
let delete_promises = []
|
|
folders_to_delete.forEach(dir => delete_promises.push(rmdir(dir)))
|
|
folders_to_delete.forEach(dir => delete_promises.push(remove_file(dir + '.htaccess')))
|
|
await Promise.all(delete_promises)
|
|
// create the new directories & transfer the files
|
|
log(' ', chalk.green('>>'), 'Uploading assets')
|
|
let create_promises = []
|
|
dirs_to_create.forEach(dir => create_promises.push(mkdir(path.join(root_dir, dir))))
|
|
files_to_transfer.forEach(file => create_promises.push(transfer_file(file[0], path.join(root_dir, file[1]))))
|
|
await Promise.all(create_promises)
|
|
// transfer .htaccess file
|
|
log(' ', chalk.green('>>'), 'Uploading .htaccess changes')
|
|
await transfer_file(path.join(basepath, dist_path, '.htaccess'), '.htaccess')
|
|
await transfer_file(path.join(basepath, dist_path, '.htaccess'), root_dir + '.htaccess')
|
|
// close the connection
|
|
log(' ', chalk.green('>>'), 'Closing connection')
|
|
close()
|
|
resolve(root_dir)
|
|
} catch(err) {
|
|
reject(err)
|
|
}
|
|
})
|
|
} |