ehapp
Advanced tools
Comparing version 1.0.3 to 1.1.0
#!/usr/bin/env node | ||
const program = require("commander"); | ||
const path = require("path"); | ||
const chalk = require("chalk"); | ||
const inquirer = require("inquirer"); | ||
const ora = require("ora"); | ||
const package = require("../package.json"); | ||
const { templates, questions, initTemplateDefault } = require("./utils.js"); | ||
const { NodeSSH } = require("node-ssh"); | ||
const { | ||
templates, | ||
initQus, | ||
initTemplateDefault, | ||
deployQus, | ||
getFilesDir, | ||
} = require("./utils.js"); | ||
const ssh = new NodeSSH(); | ||
program | ||
@@ -14,2 +25,3 @@ .version(package.version, null, "output the current version of the ehapp") | ||
.option("-i, --init", "create a new app project") | ||
.option("-d, --deploy", "deploy app to server") | ||
.helpOption("-h, --help", "output usage information of the ehapp"); | ||
@@ -19,3 +31,5 @@ | ||
if (JSON.stringify(program.opts()) === "{}") { | ||
const options = program.opts(); | ||
if (JSON.stringify(options) === "{}") { | ||
console.log( | ||
@@ -26,3 +40,3 @@ chalk.red("please use (ehapp -h or --help) to get usage information") | ||
if (program.opts() && program.opts().list) { | ||
if (options && options.list) { | ||
// 查看可用模版列表 | ||
@@ -34,5 +48,5 @@ for (let key in templates) { | ||
if (program.opts() && program.opts().init) { | ||
if (options && options.init) { | ||
// 初始化项目 | ||
inquirer.prompt(questions).then((answers) => { | ||
inquirer.prompt(initQus).then((answers) => { | ||
let url = templates[answers.template.split(" ")[0]].downloadUrl; | ||
@@ -42,1 +56,47 @@ initTemplateDefault(answers, url); | ||
} | ||
if (options && options.deploy) { | ||
// 部署项目 | ||
inquirer.prompt(deployQus).then(async (answers) => { | ||
const { ip, offline, isBuild } = answers; | ||
if (isBuild) { | ||
const spinner = ora(`${chalk.green("连接服务...")}`).start(); | ||
try { | ||
await ssh.connect({ | ||
host: ip, | ||
username: "root", | ||
password: "123456", | ||
}); | ||
spinner.text = `${chalk.green("上传文件...")}`; | ||
const dirArr = getFilesDir(offline); | ||
const pArr = []; | ||
dirArr.forEach((item) => { | ||
const { local, remote } = item; | ||
pArr.push( | ||
ssh.putDirectory(local, remote, { | ||
concurrency: 5, | ||
validate: (itemPath) => { | ||
const baseName = path.basename(itemPath); | ||
return ( | ||
baseName.substr(0, 1) !== "." && baseName !== "node_modules" | ||
); | ||
}, | ||
}) | ||
); | ||
}); | ||
try { | ||
await Promise.all(pArr); | ||
spinner.succeed("🚩🚩🚩---部署成功!---🚩🚩🚩"); | ||
process.exit(); | ||
} catch (error) { | ||
spinner.fail("文件上传失败"); | ||
console.log(chalk.red(error)); | ||
process.exit(1); | ||
} | ||
} catch (error) { | ||
spinner.fail("服务器连接失败"); | ||
console.log(chalk.red(error)); | ||
} | ||
} | ||
}); | ||
} |
const fs = require("fs"); | ||
const path = require("path"); | ||
const execSync = require('child_process').execSync; | ||
const execSync = require("child_process").execSync; | ||
const chalk = require("chalk"); | ||
@@ -36,3 +36,3 @@ const ora = require("ora"); | ||
const questions = [ | ||
const initQus = [ | ||
{ | ||
@@ -63,3 +63,3 @@ type: "input", | ||
message: "请输入项目简介", | ||
suffix: '(enter 跳过)' | ||
suffix: "(enter 跳过)", | ||
}, | ||
@@ -70,3 +70,3 @@ { | ||
message: "请输入作者名称", | ||
suffix: '(enter 跳过)' | ||
suffix: "(enter 跳过)", | ||
}, | ||
@@ -81,2 +81,35 @@ { | ||
const deployQus = [ | ||
{ | ||
type: "confirm", | ||
message: chalk.green("是否已经打包完成"), | ||
name: "isBuild", | ||
suffix: "(enter 确认)", | ||
}, | ||
{ | ||
type: "list", | ||
name: "offline", | ||
message: chalk.green("是否为离线App"), | ||
choices: ["No", "Yes"], | ||
when: (answers) => { | ||
return answers.isBuild; | ||
}, | ||
}, | ||
{ | ||
type: "input", | ||
name: "ip", | ||
message: "请输入单元环境ip地址", | ||
validate: (val) => { | ||
const pattern = /((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}/g; | ||
if (!pattern.test(val)) { | ||
return console.log(chalk.red("\n👉 ip 地址不合法")); | ||
} | ||
return true; | ||
}, | ||
when: (answers) => { | ||
return answers.isBuild; | ||
}, | ||
}, | ||
]; | ||
const downloadTemplate = (gitUrl, projectName) => { | ||
@@ -109,6 +142,6 @@ const spinner = ora(`${chalk.green("download template...")}`).start(); | ||
console.log( | ||
`${chalk.red(error)}\n | ||
`${chalk.red(error)}\n | ||
delete the .git file fail, you may need to manually delete the.git file\n | ||
${command}` | ||
); | ||
); | ||
} | ||
@@ -127,4 +160,6 @@ return new Promise((resolve, reject) => { | ||
packageContent.description = description; | ||
if (template.split(" ")[0].includes('hooks')) { | ||
packageContent.config.commitizen.path = './' + path.join(projectName, packageContent.config.commitizen.path); | ||
if (template.split(" ")[0].includes("hooks")) { | ||
packageContent.config.commitizen.path = | ||
"./" + | ||
path.join(projectName, packageContent.config.commitizen.path); | ||
} | ||
@@ -153,6 +188,6 @@ fs.writeFile( | ||
console.log( | ||
`${chalk.bold.cyan("ehapp: ")} "A new app project has been created!"\n | ||
`${chalk.bold.cyan("ehapp: ")} "A new app project has been created!"\n | ||
🚩🚩🚩--- happy coding ---🚩🚩🚩\n | ||
next:cd ${projectName} && npm/cnpm install && npm start` | ||
); | ||
); | ||
} catch (error) { | ||
@@ -163,6 +198,47 @@ console.log(chalk.red(error)); | ||
const getFilesDir = (offline) => { | ||
const dirArr = []; | ||
const basename = path.basename(process.cwd()); | ||
let notExitFiles = 0; | ||
const remoteBaseName = "/data1/ehserver/server/resources/"; | ||
if (offline === "Yes") { | ||
const humpName = basename.replace(/\-(\w)/g, (all, letter) => { | ||
return letter.toUpperCase(); | ||
}); | ||
dirArr.push({ | ||
local: process.cwd(), | ||
remote: `${remoteBaseName}nar/${humpName}`, | ||
}); | ||
} | ||
for (const item of ["build", "dist", "b"]) { | ||
const dir = path.join(process.cwd(), item); | ||
try { | ||
const res = fs.statSync(dir); | ||
if (res.isDirectory()) { | ||
dirArr.push({ | ||
local: dir, | ||
remote: `${remoteBaseName}${basename}/${item}`, | ||
}); | ||
break; | ||
} | ||
} catch (error) { | ||
notExitFiles++; | ||
continue; | ||
} | ||
} | ||
if (notExitFiles === 3) { | ||
dirArr.push({ | ||
local: process.cwd(), | ||
remote: `${remoteBaseName}${basename}`, | ||
}); | ||
} | ||
return dirArr; | ||
}; | ||
module.exports = { | ||
templates, | ||
questions, | ||
initQus, | ||
initTemplateDefault, | ||
deployQus, | ||
getFilesDir, | ||
}; |
{ | ||
"name": "ehapp", | ||
"version": "1.0.3", | ||
"description": "a company react-app template ", | ||
"main": "index.js", | ||
"version": "1.1.0", | ||
"description": "a company react-app template & deployment tool", | ||
"scripts": { | ||
@@ -10,3 +9,4 @@ "test": "echo \"Error: no test specified\" && exit 1" | ||
"keywords": [ | ||
"react-app" | ||
"react-app", | ||
"automated deployment" | ||
], | ||
@@ -23,4 +23,5 @@ "bin": { | ||
"inquirer": "^7.3.3", | ||
"node-ssh": "^11.1.1", | ||
"ora": "^5.3.0" | ||
} | ||
} |
@@ -9,4 +9,8 @@ # 移动端项目脚手架 | ||
- [x] 自动校验模块文件名,防止文件覆盖; | ||
- [x] deploy 命令自动化部署; | ||
- [x] 自动过滤 node_modules & .vscode 等上传服务器 | ||
- [x] 部署离线App | ||
... | ||
- [ ] 基于react + typescript 项目模块开发 | ||
- [ ] 基于react + typescript 项目模块开发 | ||
- [ ] 由于公司单元环境 ip 零散 ,暂时先手动输入ip部署吧 | ||
## ehapp 脚手架使用说明 | ||
@@ -24,2 +28,5 @@ | ||
4. 自动化部署 | ||
> 先运行命令打包,然后执行 `ehapp -d` 部署项目到单元环境,部署完成即可通知测试 | ||
## 脚手架常用命令 | ||
@@ -33,1 +40,6 @@ | ||
- [x] `ehapp -h or --help // output usage information of the ehapp` | ||
- [x] `ehapp -d or ehapp --deploy // deploy app to server` | ||
## FAQ | ||
该脚手架仅支持单独部署 zapp 项目,如果部署 ehome-admin 或其它后台项目需要 运用Jenkins |
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
10837
314
43
6
+ Addednode-ssh@^11.1.1
+ Addedasn1@0.2.6(transitive)
+ Addedbcrypt-pbkdf@1.0.2(transitive)
+ Addedmake-dir@3.1.0(transitive)
+ Addednode-ssh@11.1.1(transitive)
+ Addedsb-promise-queue@2.1.0(transitive)
+ Addedsb-scandir@3.1.0(transitive)
+ Addedsemver@6.3.1(transitive)
+ Addedshell-escape@0.2.0(transitive)
+ Addedssh2@0.8.9(transitive)
+ Addedssh2-streams@0.4.10(transitive)
+ Addedstreamsearch@0.1.2(transitive)
+ Addedtweetnacl@0.14.5(transitive)