ssh2 部署静态资源

137 阅读1分钟

ssh2 部署静态资源

  • 基本的连接信息
  • 获取本地要上传文件的目录及文件
  • 检测远程目标上对应的文件夹
    • 不存在则创建
  • 上传本地文件
const path = require("path");
const Client = require("@ventose/ssh2").Client;
const { _n } = require("@ventose/utils-node");
const hostConfigs = require("./privateConfigs").deploy;

const conn = new Client();
conn.on("ready", setup).connect({
	host: hostConfigs.host,
	port: 22,
	username: hostConfigs.username,
	password: hostConfigs.password
});

async function setup() {
	function run() {
		return new Promise((sftpConnectResolve, sftpConnectReject) => {
			conn.sftp(async (err, sftp) => {
				if (err) {
					sftpConnectReject(err);
				}

				async function asyncSafeMakeDir(dirUrl) {
					if (!dirUrl) {
						return false;
					}

					if (await asyncIsExist(dirUrl)) {
						return true;
					}

					const dirParentUrl = path.dirname(dirUrl);
					if (!(await asyncIsExist(dirParentUrl))) {
						await asyncSafeMakeDir(dirParentUrl);
					}
					return await asyncMkdir(dirUrl);
				}

				function asyncMkdir(url) {
					url = url.split(path.sep).join("/");
					console.log("🚀make dir", url);
					return new Promise(resolve => {
						sftp.mkdir(url, err => {
							if (err) {
								resolve(false);
							} else {
								resolve(true);
							}
						});
					});
				}

				function asyncIsExist(url) {
					return new Promise((resolve, reject) => {
						url = url.split(path.sep).join("/");
						sftp.stat(url, (err, stats) => {
							if (err) {
								if (err.message === "No such file") {
									resolve(false);
								} else {
									reject(err);
								}
							} else {
								resolve(stats);
							}
						});
					});
				}

				function asyncUploadFile(local, remote) {
					return new Promise(resolve => {
						remote = remote.split(path.sep).join("/");
						sftp.fastPut(local, remote, err => {
							if (err) {
								resolve(false);
							} else {
								resolve(true);
							}
						});
					});
				}

				const [dirs, files] = await _n.asyncAllDirAndFile([
					path.resolve("./dist")
				]);
				// console.log(dirs, files);
				const remote_dirs = dirs.map(i =>
					path.join(hostConfigs.remoteDir + "/test/", i.split("dist")[1])
				);

				let remoteTarget;
				while ((remoteTarget = remote_dirs.pop())) {
					await asyncSafeMakeDir(remoteTarget);
				}

				const remote_files = files.map(i => [
					i,
					path.join(hostConfigs.remoteDir + "/test/", i.split("dist")[1])
				]);

				while ((remoteTarget = remote_files.pop())) {
					const [local, remote] = remoteTarget;
					await asyncUploadFile(local, remote);
				}
				sftpConnectResolve();
			});
		});
	}
	await run();
	conn.end();
}

OOP

const path = require("path");
const Client = require("@ventose/ssh2").Client;
const { _n } = require("@ventose/utils-node");
const hostConfigs = require("./privateConfigs").deploy;

function Ssh2Client(configs) {
	this.configs = configs;
	this.conn = new Client();

	this.setup = async () => {
		const { localDir, remoteBaseUrl } = this.configs;
		const localDirBaseName = path.basename(localDir);
		const [dirs, files] = await _n.asyncAllDirAndFile([path.resolve(localDir)]);
		const remote_dirs = dirs.map(i =>
			path.join(remoteBaseUrl, i.split(localDirBaseName)[1])
		);
		let remoteTarget;
		while ((remoteTarget = remote_dirs.pop())) {
			await this.asyncSafeMakeDir(remoteTarget);
		}
		const remote_files = files.map(i => [
			i,
			path.join(remoteBaseUrl, i.split(localDirBaseName)[1])
		]);

		while ((remoteTarget = remote_files.pop())) {
			const [local, remote] = remoteTarget;
			await this.asyncUploadFile(local, remote);
		}
	};

	this.asyncUploadFile = (local, remote) => {
		return new Promise(resolve => {
			remote = remote.split(path.sep).join("/");
			console.log("upload file", local, remote);
			this.sftp.fastPut(local, remote, err => {
				if (err) {
					resolve(false);
				} else {
					resolve(true);
				}
			});
		});
	};

	this.asyncIsExist = url => {
		return new Promise((resolve, reject) => {
			url = url.split(path.sep).join("/");
			this.sftp.stat(url, (err, stats) => {
				if (err) {
					if (err.message === "No such file") {
						resolve(false);
					} else {
						reject(err);
					}
				} else {
					resolve(stats);
				}
			});
		});
	};
	this.asyncMkdir = url => {
		console.log("async mkdir", url);
		url = url.split(path.sep).join("/");
		return new Promise(resolve => {
			this.sftp.mkdir(url, err => {
				if (err) {
					resolve(false);
				} else {
					resolve(true);
				}
			});
		});
	};
	this.asyncSafeMakeDir = async dirUrl => {
		if (!dirUrl) {
			return false;
		}
		if (await this.asyncIsExist(dirUrl)) {
			return true;
		}

		const dirParentUrl = path.dirname(dirUrl);
		if (!(await this.asyncIsExist(dirParentUrl))) {
			await this.asyncSafeMakeDir(dirParentUrl);
		}
		return await this.asyncMkdir(dirUrl);
	};

	this.run = functionExpression => {
		this.conn.on("ready", async () => {
			return new Promise(async (sftpConnectResolve, sftpConnectReject) => {
				this.conn.sftp(async (err, sftp) => {
					if (err) {
						console.error(err);
						sftpConnectReject(err);
					}
					this.sftp = sftp;

					if (typeof functionExpression === "function") {
						await functionExpression.call(this);
					} else {
						await this.setup();
					}
					this.conn.end();
					sftpConnectResolve(this);
				});
			});
		});
		this.conn.connect(configs);
	};
}

const ssh2Client = new Ssh2Client({
	host: hostConfigs.host,
	port: 22,
	username: hostConfigs.username,
	password: hostConfigs.password,
	localDir: "./dist",
	remoteBaseUrl: hostConfigs.remoteDir
});

ssh2Client.run();