-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
executable file
·267 lines (246 loc) · 7.28 KB
/
index.js
File metadata and controls
executable file
·267 lines (246 loc) · 7.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#!/usr/bin/env node
const inquirer = require("inquirer")
const shell = require("shelljs")
const fs = require("fs-extra")
const format = "zip-dist"
const {
formatJson,
readData,
writeData,
moveFile,
template,
execShell
} = require("./utils/index")
const { uploadFile } = require("./utils/upload")
const { startRemoteShell } = require("./utils/startShell")
shell.exec("pwd", async function(err, pwd) {
if (err) {
return
}
try {
const _pwd = getPwd(pwd)
//获取 base.json 里面的 outputName值
let { outputName: OUTPUTNAME, nodeDependencies, serveConfig } = getBaseJson(
_pwd
)
if (!OUTPUTNAME) {
throw new Error("base.json has not outputName filed")
}
nodeDependencies = checkDeps(nodeDependencies) // node 必须要有的依赖项
const defNodeTitle = getDefNodeTitle(_pwd)
const { INJECTED_MODULE, BASE, NODE_TITLE } = await getInputInfo(
defNodeTitle
)
let nodeTitle = "node server --title="
nodeTitle = `${nodeTitle}${NODE_TITLE}`
console.log(`INJECTED_MODULE is: ${INJECTED_MODULE}`)
console.log(`BASE is: ${BASE}`)
console.log(`NODE_TITLE is: ${nodeTitle}`)
// 首先更改 pkg里面的 scripts 下面的 serve 值
changePkg(_pwd, nodeTitle)
console.log("OUTPUTNAMEOUTPUTNAME", OUTPUTNAME)
const outputName = getOutputName(INJECTED_MODULE, OUTPUTNAME)
console.log(`Dir name is: ${outputName}`)
// 先找到 当前目录下 所有包含projectName的文件 或者 文件夹
const shouldDelNames = await getDeleteNames(_pwd)
console.log("删除文件>>>>>", shouldDelNames)
// # 删除之前打包好的项目
const delArrPro = shouldDelNames.map(v => {
return removeFile(`${_pwd}/${v}`)
})
if (delArrPro.length) {
await Promise.all(delArrPro)
}
// 替换 base
changeBase(_pwd, BASE)
// 打包
await execShell(
"NODE_ENV=production npm run build",
"build failed, you need to find why!?!?!?!"
)
// 把改dist server package.json 移动到 outputName 下面
const moveArr = ["package.json", "dist", "server"].map(v => {
return moveFile(`${_pwd}/${v}`, `${_pwd}/${outputName}/${v}`)
})
await Promise.all(moveArr)
// 拷贝stop.sh到打包目录
writeStopToBin(_pwd, outputName)
shell.cd(`${_pwd}/${outputName}`)
// 安装node的依赖
const installNodeStrShell = getNodeStrShell(nodeDependencies)
await execShell(
installNodeStrShell,
"Install node runtime dependencies failed, check network first!"
)
shell.cd(`${_pwd}`)
await execShell(
`zip -r "${outputName}.zip" ${outputName}`,
"Install runtime dependencies failed, check network first!"
)
console.log("打包成功>>>>>>>>")
await uploadZipAndExecStartShell({
...serveConfig,
sourcePath: `${outputName}.zip`
})
process.exit(0)
} catch (err) {
console.log("build err>>>>>>>>>>>>>", err)
process.exit(0)
}
})
async function uploadZipAndExecStartShell(props) {
const { host, username, password, targetPath } = props
if (!host || !username || !password || !targetPath) {
throw new Error("host or username or password or targetPath must config")
}
// 上传
await uploadFile(props)
// 上传后启动 start.sh
await startRemoteShell(props)
}
function getDefNodeTitle(_pwd) {
const {
scripts: { serve: nodeTitle }
} = readData(`${_pwd}/package.json`)
console.log("def nodeTitle", nodeTitle)
const format = "node server --title="
const arr = nodeTitle.split(format)
if (arr.length !== 2) {
throw new Error("scripts serve format error")
}
return arr[1]
}
function checkDeps(nodeDependencies) {
if (!nodeDependencies || nodeDependencies.length === 0) {
nodeDependencies = ["express", "replace-in-file"]
} else {
if (!nodeDependencies.includes("express")) {
nodeDependencies.push("express")
}
if (!nodeDependencies.includes("replace-in-file")) {
nodeDependencies.push("replace-in-file")
}
}
return nodeDependencies
}
function getNodeStrShell(arr) {
let str = "npm install"
for (let v of arr) {
str = `${str} ${v}`
}
return str
}
function getPwd(pwd) {
const _pwd = pwd.trim() // 为啥有空格啊 坑死我了
console.log("pwd.....", _pwd)
return _pwd
}
function getBaseJson(_pwd) {
return readData(`${_pwd}/base.json`)
}
function changeBase(_pwd, base) {
let data = readData(`${_pwd}/base.json`)
data.proBase = base
writeData(`${_pwd}/base.json`, formatJson(data))
}
function writeStopToBin(_pwd, outputName) {
const {
scripts: { serve: nodeTitle }
} = readData(`${_pwd}/package.json`)
// 把nodeTITLE 写入到 shell/stop里面
const data = template(`${_pwd}/shells/stop.sh`, {
NODE_TITAL: nodeTitle
})
writeData(`${_pwd}/${outputName}/bin/stop.sh`, data)
}
function changePkg(_pwd, nodeTitle) {
let data = readData(`${_pwd}/package.json`)
data.scripts.serve = nodeTitle
writeData(`${_pwd}/package.json`, formatJson(data))
}
async function getInputInfo(defNodeTitle) {
return new Promise((reslove, reject) => {
inquirer
.prompt([
{
type: "input",
name: "INJECTED_MODULE",
message: "Please input INJECTED_MODULE",
default: "dfocus"
},
{
type: "input",
name: "BASE",
message: "Please input deploy directory",
default: "/"
},
{
type: "input",
name: "NODE_TITLE",
message: "Please input node_title",
default: defNodeTitle
}
// {
// type: "input",
// name: "OUTPUTNAME",
// message: "Please input outputName",
// default: defOutputName
// }
])
.then(answers => {
// const _outputName = dealwithOutputName(answers.OUTPUTNAME);
reslove({
...answers
// OUTPUTNAME: _outputName
})
})
})
}
function dealwithOutputName(OUTPUTNAME) {
// 对OUTPUTNAME 字段特殊处理下 如果用户输入是 test-ads 那就给他转化为 test-ads-zip-dist,如果用户输入是 test-ads-zip-dist 就不处理
const arr = OUTPUTNAME.split(format)
// 如果 defOutputName "bmw-desking-web-zip-dist" split 后 为 ["bmw-desking-web-", ""]
if (arr.length !== 2) {
// 不等于2 说明test-ads-zip-dist这种格式
return `${OUTPUTNAME}-${format}`
}
return OUTPUTNAME
}
async function getDeleteNames(filePath) {
const files = await fs.readdir(filePath)
return files.filter(v => {
if (v.includes(format)) {
// 获取所有包含 zip-dist 的文件
return true
}
return false
})
}
async function removeFile(path) {
return new Promise((reslove, reject) => {
fs.remove(path, info => {
reslove(info)
})
})
}
function getProjectName(defOutputName) {
const arr = defOutputName.split(format)
// 如果 defOutputName "bmw-desking-web-zip-dist" split 后 为 ["bmw-desking-web-", ""]
if (arr.length !== 2) {
return ""
}
return arr[0]
}
function getOutputName(INJECTED_MODULE, defOutputName) {
if (!INJECTED_MODULE) {
return defOutputName
}
if (INJECTED_MODULE === "dfocus") {
return defOutputName
}
const projectName = getProjectName(defOutputName)
if (!projectName) {
return defOutputName
}
return `${projectName}${INJECTED_MODULE}-${format}`
}