diff --git a/deploy.js b/deploy.js index 3d9862b..81b1ff2 100644 --- a/deploy.js +++ b/deploy.js @@ -5,60 +5,103 @@ const path = require('path') const commander = require('commander') const deepmerge = require('deepmerge') -var Config = { deploy: {} } +// 默认参数 +const Config = { + deploy: { + from: './dist', + toTarget: 'connection', + + connection: { + server: 'ssh', + host: undefined, + port: 22, + dir: undefined, + dist: 'dist', + repo: undefined, + branch: 'master', + gitname: undefined, + gitemail: undefined, + user: undefined, + password: undefined, + key: `${process.env.HOME}/.ssh/id_rsa`, + }, + conn_ssh: { + server: 'ssh', + host: undefined, + port: 22, + dir: undefined, + dist: 'dist', + user: undefined, + password: undefined, + key: `${process.env.HOME}/.ssh/id_rsa`, + }, + conn_git: { + server: 'git', + repo: undefined, + branch: 'master', + gitname: undefined, + gitemail: undefined, + user: undefined, + password: undefined, + key: `${process.env.HOME}/.ssh/id_rsa`, + } + } +} // 读取配置文件 try { let configFile - if (fs.existsSync(configFile=path.join(process.cwd(), 'ConfigBasic.js'))) { - Config = require(configFile) - console.info(`${configFile} loaded`) - } - if (fs.existsSync(configFile=path.join(process.cwd(), 'ConfigCustom.js'))) { // 如果存在,覆盖掉 ConfigBasic 里的默认参数 - Config = deepmerge(Config, require(configFile)) // 注意,objectMerge后,产生了一个新的对象,而不是在原来的Config里添加 - console.info(`${configFile} loaded`) - } - if (fs.existsSync(configFile=path.join(process.cwd(), 'ConfigSecret.js'))) { // 如果存在,覆盖掉 ConfigBasic 和 ConfigCustom 里的参数 - Config = deepmerge(Config, require(pconfigFile)) + if (fs.existsSync(configFile=path.join(process.cwd(), 'ConfigDeploy.js'))) { + Config = deepmerge(Config, require(configFile)) console.info(`${configFile} loaded`) } } catch (err) { console.error('Loading config files failed: ' + err.message) } +Config.deploy.connection = Config.deploy[Config.deploy.toTarget] +// 读取命令行参数 commander .version('1.0', '-v, --version') // 默认是 -V。如果要 -v,就要加 '-v --version' - .option('-f, --from ', `from path to copy from. Default to ${Config.deploy.from}`) - .option('-t, --type ', `Deploy to server type, ssh or git. Default to ${Config.deploy.type}`) - .option('-H, --host ', `Host IP or domain name of the target server. Default to ${Config.deploy.host}`) - .option('-P, --port ', `Ssh port number of the target server. Default to ${Config.deploy.port}`) - .option('-D, --dir ', `Destination path to deploy on the target server. Default to ${Config.deploy.dir}`) - .option('-d, --dist ', `Destination folder to deploy on the target server. Default to ${Config.deploy.dist}`) - .option('-r, --repo ', `git repo address. Default to ${Config.deploy.repo}`) - .option('-b, --branch ', `git user name. Default to ${Config.deploy.gitname}`) - .option('-e, --gitemail ', `git user email. Default to ${Config.deploy.gitemail}`) - .option('-u, --user ', `User id to login the target server. Default to ${Config.deploy.user}`) - .option('-k, --key ', `User private key file to login the target server. Default to ${Config.deploy.key}`) - .option('-p, --password ', `User password to login the target server. You may have to enclose it in "". Default to "${Config.deploy.password}"`) + .option('-f, --from ', `local path to copy from. Default to ${Config.deploy.from}`) + .option('-t, --toTarget ', `connection section in config. Default to ${Config.deploy.toTarget}`) + + .option('-s, --server ', `server type, git or ssh. Default to ${Config.deploy.connection.type}`) + + .option('-H, --host ', `Host IP or domain name of the target server. Default to ${Config.deploy.connection.host}`) + .option('-P, --port ', `Ssh port number of the target server. Default to ${Config.deploy.connection.port}`) + .option('-D, --dir ', `Destination path to deploy on the target server. Default to ${Config.deploy.connection.dir}`) + .option('-d, --dist ', `Destination folder to deploy on the target server. Default to ${Config.deploy.connection.dist}`) + + .option('-r, --repo ', `git repo address. Default to ${Config.deploy.connection.repo}`) + .option('-b, --branch ', `git repo branch. Default to ${Config.deploy.connection.branch}`) + .option('-n, --gitname ', `git user name. Default to ${Config.deploy.connection.gitname}`) + .option('-e, --gitemail ', `git user email. Default to ${Config.deploy.connection.gitemail}`) + + .option('-u, --user ', `User id to login the target server. Default to ${Config.deploy.connection.user}`) + .option('-k, --key ', `User private key file to login the target server. Default to ${Config.deploy.connection.key}`) + .option('-p, --password ', `User password to login the target server. You may have to enclose it in "". Default to "${Config.deploy.connection.password}"`) .parse(process.argv) -const privateKeyFile = commander.key || Config.deploy.key || `${process.env.HOME}/.ssh/id_rsa` +Config.deploy.from = commander.from || Config.deploy.from +Config.deploy.connection = Config.deploy[commander.toTarget || Config.deploy.toTarget] // 使用用户指定的连接 const connection = { - from: commander.from || Config.deploy.from || './dist', - type: commander.type || Config.deploy.type || 'ssh', - host: commander.host || Config.deploy.host, - port: commander.port || Config.deploy.port || 22, - dir: commander.dir || Config.deploy.dir, // 目标服务器上的目录。似乎该目录必须已经存在于服务器上 - dist: commander.dist || Config.deploy.dist || 'dist', // 新系统将发布在这个文件夹里。建议为dist,和npm run build产生的目录一致,这样既可以远程自动部署,也可以直接登录服务器手动部署。 - repo: commander.repo || Config.deploy.repo, - branch: commander.branch || Config.deploy.branch || 'master', - gitname: commander.gitname || Config.deploy.gitname, - gitemail: commander.gitemail || Config.deploy.gitemail, - username: commander.user || Config.deploy.user, - privateKey: fs.existsSync(privateKeyFile) ? privateKeyFile : undefined, - password: commander.password || Config.deploy.password, + server: commander.server || Config.deploy.connection.server, + + host: commander.host || Config.deploy.connection.host, + port: commander.port || Config.deploy.connection.port, + dir: commander.dir || Config.deploy.connection.dir, // 目标服务器上的目录。似乎该目录必须已经存在于服务器上 + dist: commander.dist || Config.deploy.connection.dist, // 新系统将发布在这个文件夹里。建议为dist,和npm run build产生的目录一致,这样既可以远程自动部署,也可以直接登录服务器手动部署。 + + repo: commander.repo || Config.deploy.connection.repo, + branch: commander.branch || Config.deploy.connection.branch, + gitname: commander.gitname || Config.deploy.connection.gitname, + gitemail: commander.gitemail || Config.deploy.connection.gitemail, + + username: commander.user || Config.deploy.connection.user, + privateKey: fs.existsSync(commander.key || Config.deploy.key) ? (commander.key || Config.deploy.key) : undefined, + password: commander.password || Config.deploy.connection.password, tryKeyboard: true, onKeyboardInteractive: (name, instructions, instructionsLang, prompts, finish) => { // 不起作用 if (prompts.length > 0 && prompts[0].prompt.toLowerCase().includes('password')) { @@ -66,16 +109,17 @@ const connection = { } }, } -console.log(` connection = ${JSON.stringify(connection)}`) + +console.log(` deploy from ${Config.deploy.from} to ${JSON.stringify(connection)}`) if (connection.type==='ssh') { - deployToSsh() + deployToSsh(connection) }else if (connection.type==='git'){ - deployToGit() + deployToGit(connection) } /** ********************** 连接到 Ssh主机,拷贝文件到指定路径 ************* **/ -function deployToSsh(){ +function deployToSsh(connection){ const ssh = new (require('node-ssh'))() function subDirs (path) { @@ -104,7 +148,7 @@ function deployToSsh(){ await ssh.execCommand(`mv ${connection.dist} ${connection.dist}-backup-${new Date().toISOString()}`, { cwd: connection.dir }) console.log(`[ mkdir ${connection.dist} ... ]`) await ssh.execCommand(`mkdir ${connection.dist}`, { cwd: connection.dir }) - const toCreate = necessaryPath(path.join('./', connection.from)) + const toCreate = necessaryPath(path.join('./', Config.deploy.from)) for (const name of toCreate) { console.log(`[ mkdir ${connection.dist}/${name.join('/')} ... ]`) await ssh.execCommand(`mkdir ${connection.dist}/${name.join('/')}`, { cwd: connection.dir }) @@ -112,7 +156,7 @@ function deployToSsh(){ let err console.log(`[ Upload to ${connection.dir}/${connection.dist} ... ]`) - await ssh.putDirectory(path.join('./', connection.from), `${connection.dir}/${connection.dist}`, { + await ssh.putDirectory(path.join('./', Config.deploy.from), `${connection.dir}/${connection.dist}`, { concurrency: 10, recursive: true, validate: itemPath => { @@ -139,7 +183,7 @@ function deployToSsh(){ } /** ********************** 连接到 Git主机,拷贝文件到指定路径 ************* **/ -function deployToGit(){ +function deployToGit(connection){ const pathFn = require('path') const fs = require('hexo-fs') const chalk = require('chalk') @@ -201,7 +245,7 @@ function deployToGit(){ function exec() { const baseDir = '' const deployDir = pathFn.join(baseDir, '.deploy_git') - const publicDir = connection.from + const publicDir = Config.deploy.from let extendDirs = connection.extend_dirs const ignoreHidden = connection.ignore_hidden const ignorePattern = connection.ignore_pattern