electron-version-deployer-cli 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +496 -0
- package/dist/const.d.ts +2 -0
- package/dist/helpers/fetchRemotePkgJSON.d.ts +2 -0
- package/dist/index.cjs.js +10 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.es.js +10 -0
- package/dist/main.cjs.js +306 -0
- package/dist/main.d.ts +18 -0
- package/dist/main.es.js +306 -0
- package/dist/templates/evd.config.ts +19 -0
- package/dist/templates/newVersionDialog.html +163 -0
- package/dist/types/EVDConfigType.d.ts +20 -0
- package/dist/utils/compareObjectsIsEqual.d.ts +1 -0
- package/dist/utils/versionToNum.d.ts +1 -0
- package/package.json +55 -0
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
const commander = require("commander");
|
|
4
|
+
const pkgUp = require("pkg-up");
|
|
5
|
+
const node_fs = require("node:fs");
|
|
6
|
+
const logSymbols = require("log-symbols");
|
|
7
|
+
const prompts = require("@inquirer/prompts");
|
|
8
|
+
const node_path = require("node:path");
|
|
9
|
+
const vite = require("vite");
|
|
10
|
+
const vm = require("node:vm");
|
|
11
|
+
const node_child_process = require("node:child_process");
|
|
12
|
+
const parseChangelog = require("changelog-parser");
|
|
13
|
+
const marked = require("marked");
|
|
14
|
+
const jsdom = require("jsdom");
|
|
15
|
+
const DOMPurify = require("dompurify");
|
|
16
|
+
const archiver = require("archiver");
|
|
17
|
+
const node_https = require("node:https");
|
|
18
|
+
const download = require("download");
|
|
19
|
+
const pkgPath = pkgUp.sync();
|
|
20
|
+
function r(...paths) {
|
|
21
|
+
if (!pkgPath)
|
|
22
|
+
return "./";
|
|
23
|
+
if (paths.length === 0)
|
|
24
|
+
return node_path.dirname(node_path.resolve(pkgPath));
|
|
25
|
+
return node_path.join(node_path.dirname(node_path.resolve(pkgPath)), ...paths);
|
|
26
|
+
}
|
|
27
|
+
function formatBytes(bytes) {
|
|
28
|
+
if (bytes < 1024) {
|
|
29
|
+
return bytes + " B";
|
|
30
|
+
} else if (bytes < 1048576) {
|
|
31
|
+
return (bytes / 1024).toFixed(2) + " KB";
|
|
32
|
+
} else {
|
|
33
|
+
return (bytes / 1048576).toFixed(2) + " MB";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const CLI_NAME = "electron-version-deployer-cli";
|
|
37
|
+
const CONFIG_FILE_NAME = "evd.config.js";
|
|
38
|
+
commander.program.command("init").option("-y", "自动确认初始化", false).description("生成配置文件").action(async (source, destination) => {
|
|
39
|
+
const pkgPath2 = pkgUp.sync();
|
|
40
|
+
if (!pkgPath2)
|
|
41
|
+
return console.log(
|
|
42
|
+
logSymbols.error,
|
|
43
|
+
"当前 cwd 下找不到 package.json 文件 \n 请确保该命令在 node 项目中执行!"
|
|
44
|
+
);
|
|
45
|
+
const pkgContent = JSON.parse(node_fs.readFileSync(pkgPath2, "utf-8"));
|
|
46
|
+
const name = pkgContent.name.split("/").pop().replaceAll("-", "");
|
|
47
|
+
const defaultConfig = {
|
|
48
|
+
compileCommand: "compile:mac",
|
|
49
|
+
changelogsPath: "CHANGELOG.md",
|
|
50
|
+
sources: {
|
|
51
|
+
folder: `dist/mac-arm64/${name}.app/Resources/app`,
|
|
52
|
+
nodeModules: "node_modules",
|
|
53
|
+
codes: "build",
|
|
54
|
+
packageJSON: "package.json"
|
|
55
|
+
},
|
|
56
|
+
netlify: {
|
|
57
|
+
url: "",
|
|
58
|
+
token: "",
|
|
59
|
+
siteID: ""
|
|
60
|
+
},
|
|
61
|
+
prebuiltConfig: {}
|
|
62
|
+
};
|
|
63
|
+
if (!source.y) {
|
|
64
|
+
defaultConfig.compileCommand = await prompts.input({
|
|
65
|
+
message: "请输入编译命令",
|
|
66
|
+
default: defaultConfig.compileCommand
|
|
67
|
+
// validate(str) {
|
|
68
|
+
// const scripts = pkgContent.scripts ?? {};
|
|
69
|
+
// return Promise.resolve(
|
|
70
|
+
// scripts[str] ? true : `无法在 package.json 中找到该命令!`
|
|
71
|
+
// );
|
|
72
|
+
// },
|
|
73
|
+
});
|
|
74
|
+
defaultConfig.changelogsPath = await prompts.input({
|
|
75
|
+
message: "请输入 changelogs 文件位置(以项目根目录为准的相对路径)",
|
|
76
|
+
default: defaultConfig.changelogsPath
|
|
77
|
+
// validate(str) {
|
|
78
|
+
// return Promise.resolve(
|
|
79
|
+
// existsSync(r(str))
|
|
80
|
+
// ? /\.md$/.test(str)
|
|
81
|
+
// ? true
|
|
82
|
+
// : "该文件必须是以 .md 结尾的 Markdown 文件"
|
|
83
|
+
// : "该文件不存在!"
|
|
84
|
+
// );
|
|
85
|
+
// },
|
|
86
|
+
});
|
|
87
|
+
defaultConfig.sources.folder = await prompts.input({
|
|
88
|
+
message: "请输入源文件目录",
|
|
89
|
+
default: `dist/mac-arm64/myapp.app/Resources/app`
|
|
90
|
+
});
|
|
91
|
+
defaultConfig.sources.nodeModules = await prompts.input({
|
|
92
|
+
message: "请输入源文件 node_modules 目录",
|
|
93
|
+
default: defaultConfig.sources.nodeModules
|
|
94
|
+
});
|
|
95
|
+
defaultConfig.sources.codes = await prompts.input({
|
|
96
|
+
message: "请输入源文件 逻辑代码目录",
|
|
97
|
+
default: defaultConfig.sources.codes
|
|
98
|
+
});
|
|
99
|
+
defaultConfig.sources.packageJSON = await prompts.input({
|
|
100
|
+
message: "请输入源文件 package.json 路径",
|
|
101
|
+
default: defaultConfig.sources.packageJSON
|
|
102
|
+
});
|
|
103
|
+
defaultConfig.netlify.url = await prompts.input({
|
|
104
|
+
message: "请输入 Netlify 网站域名"
|
|
105
|
+
});
|
|
106
|
+
defaultConfig.netlify.token = await prompts.input({
|
|
107
|
+
message: "请输入 Netlify Token"
|
|
108
|
+
});
|
|
109
|
+
defaultConfig.netlify.siteID = await prompts.input({
|
|
110
|
+
message: "请输入 Netlify SiteID"
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
let evdConfigContent = node_fs.readFileSync(
|
|
114
|
+
node_path.join(node_path.resolve(__dirname), "templates", "evd.config.ts"),
|
|
115
|
+
"utf-8"
|
|
116
|
+
);
|
|
117
|
+
evdConfigContent = evdConfigContent.replace(/\/\/\s+@ts-nocheck\n/, "");
|
|
118
|
+
evdConfigContent = evdConfigContent.replace(/"@\/index"/, `"${CLI_NAME}"`);
|
|
119
|
+
Object.entries(defaultConfig).map(([key, value]) => {
|
|
120
|
+
if (typeof value === "object") {
|
|
121
|
+
Object.entries(value).map(([_key, _value]) => {
|
|
122
|
+
evdConfigContent = evdConfigContent.replace(
|
|
123
|
+
new RegExp(`__${key}_${_key}__`),
|
|
124
|
+
`"${_value}"`
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
} else {
|
|
128
|
+
evdConfigContent = evdConfigContent.replace(
|
|
129
|
+
new RegExp(`__${key}__`),
|
|
130
|
+
`"${value}"`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
node_fs.writeFileSync(r(CONFIG_FILE_NAME), evdConfigContent, "utf-8");
|
|
135
|
+
console.log(
|
|
136
|
+
logSymbols.success,
|
|
137
|
+
`生成配置文件 ${r(CONFIG_FILE_NAME)} 成功!`
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
async function getConfigs() {
|
|
141
|
+
const configFilePath = r(CONFIG_FILE_NAME);
|
|
142
|
+
if (!node_fs.existsSync(configFilePath)) {
|
|
143
|
+
throw new Error(`无法找到 ${configFilePath} 文件! `);
|
|
144
|
+
}
|
|
145
|
+
return await bundleConfigFileAndRead(r(CONFIG_FILE_NAME));
|
|
146
|
+
}
|
|
147
|
+
async function bundleConfigFileAndRead(configFilePath) {
|
|
148
|
+
return new Promise((resolve) => {
|
|
149
|
+
vite.build({
|
|
150
|
+
mode: "development",
|
|
151
|
+
configFile: false,
|
|
152
|
+
logLevel: "error",
|
|
153
|
+
root: r(),
|
|
154
|
+
resolve: {
|
|
155
|
+
alias: {
|
|
156
|
+
[CLI_NAME]: node_path.resolve(__dirname, "./index.es.js")
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
build: {
|
|
160
|
+
write: false,
|
|
161
|
+
commonjsOptions: {
|
|
162
|
+
esmExternals: true
|
|
163
|
+
},
|
|
164
|
+
emptyOutDir: false,
|
|
165
|
+
sourcemap: false,
|
|
166
|
+
cssCodeSplit: false,
|
|
167
|
+
minify: false,
|
|
168
|
+
lib: {
|
|
169
|
+
entry: configFilePath,
|
|
170
|
+
// 注意,由于我们需要将文件打包到一起,所以用的 iife 格式
|
|
171
|
+
// 这里给一个全局名称,方便等等在上下文中获取
|
|
172
|
+
name: "_",
|
|
173
|
+
formats: ["iife"]
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}).then((data) => {
|
|
177
|
+
const script = new vm.Script(data[0].output[0].code);
|
|
178
|
+
const ctx = {};
|
|
179
|
+
script.runInNewContext(ctx);
|
|
180
|
+
resolve(ctx._);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
function archiveFiles(outputPath, files) {
|
|
185
|
+
return new Promise((res, rej) => {
|
|
186
|
+
const output = node_fs.createWriteStream(outputPath);
|
|
187
|
+
const archive = archiver("zip");
|
|
188
|
+
output.on("close", function() {
|
|
189
|
+
console.log(
|
|
190
|
+
logSymbols.success,
|
|
191
|
+
`压缩完成 ${node_path.basename(outputPath)} ${formatBytes(archive.pointer())}`
|
|
192
|
+
);
|
|
193
|
+
res();
|
|
194
|
+
});
|
|
195
|
+
archive.on("error", function(err) {
|
|
196
|
+
rej(err);
|
|
197
|
+
});
|
|
198
|
+
archive.pipe(output);
|
|
199
|
+
for (let filePath of files) {
|
|
200
|
+
if (~filePath.indexOf("package.json")) {
|
|
201
|
+
archive.file(filePath, { name: node_path.basename(filePath) });
|
|
202
|
+
} else {
|
|
203
|
+
archive.directory(filePath, node_path.basename(filePath));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
archive.finalize();
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
commander.program.command("prepare").description(
|
|
210
|
+
"部署前的准备工作,如获取编译软件获取逻辑代码,生成 changelog 等"
|
|
211
|
+
).action(async (source, destination) => {
|
|
212
|
+
const configs = await getConfigs();
|
|
213
|
+
try {
|
|
214
|
+
await genTmpFolder();
|
|
215
|
+
await compile(configs);
|
|
216
|
+
await genChangelog(configs);
|
|
217
|
+
await copySourceAndZipFiles(configs);
|
|
218
|
+
} catch (e) {
|
|
219
|
+
console.log(logSymbols.error, e.toString());
|
|
220
|
+
}
|
|
221
|
+
console.log(logSymbols.info, "请执行 evd deploy 命令进行部署");
|
|
222
|
+
});
|
|
223
|
+
async function copySourceAndZipFiles(configs) {
|
|
224
|
+
const logicCodeZipPath = r("node_modules/.evd/logicCode.zip");
|
|
225
|
+
const fullCodeZipPath = r("node_modules/.evd/fullCode.zip");
|
|
226
|
+
const nodeModulesPath = node_path.join(
|
|
227
|
+
node_path.resolve(configs.sources.folder),
|
|
228
|
+
configs.sources.nodeModules
|
|
229
|
+
);
|
|
230
|
+
const codesPath = node_path.join(
|
|
231
|
+
node_path.resolve(configs.sources.folder),
|
|
232
|
+
configs.sources.codes
|
|
233
|
+
);
|
|
234
|
+
const packageJSONPath = node_path.join(
|
|
235
|
+
node_path.resolve(configs.sources.folder),
|
|
236
|
+
configs.sources.packageJSON
|
|
237
|
+
);
|
|
238
|
+
if (!node_fs.existsSync(nodeModulesPath)) {
|
|
239
|
+
throw new Error(
|
|
240
|
+
`${r(
|
|
241
|
+
configs.sources.nodeModules
|
|
242
|
+
)} 文件夹不存在,请检查 configs.sources.nodeModules 配置是否正确!`
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
if (!node_fs.existsSync(codesPath)) {
|
|
246
|
+
throw new Error(
|
|
247
|
+
`${r(
|
|
248
|
+
configs.sources.codes
|
|
249
|
+
)} 文件夹不存在,请检查 configs.sources.codes 配置是否正确!`
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
if (!node_fs.existsSync(packageJSONPath)) {
|
|
253
|
+
throw new Error(
|
|
254
|
+
`${r(
|
|
255
|
+
configs.sources.packageJSON
|
|
256
|
+
)} 文件夹不存在,请检查 configs.sources.packageJSON 配置是否正确!`
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
await archiveFiles(fullCodeZipPath, [
|
|
260
|
+
nodeModulesPath,
|
|
261
|
+
codesPath,
|
|
262
|
+
packageJSONPath
|
|
263
|
+
]);
|
|
264
|
+
await archiveFiles(logicCodeZipPath, [codesPath, packageJSONPath]);
|
|
265
|
+
node_fs.copyFileSync(packageJSONPath, r("node_modules/.evd/package.json"));
|
|
266
|
+
console.log(logSymbols.success, "更新包创建成功!");
|
|
267
|
+
}
|
|
268
|
+
async function genChangelog(configs) {
|
|
269
|
+
if (!node_fs.existsSync(r(configs.changelogsPath))) {
|
|
270
|
+
throw new Error(`${r(configs.changelogsPath)} 文件不存在,请先创建!`);
|
|
271
|
+
}
|
|
272
|
+
const outputPackageJSONPath = node_path.join(
|
|
273
|
+
node_path.resolve(configs.sources.folder),
|
|
274
|
+
configs.sources.packageJSON
|
|
275
|
+
);
|
|
276
|
+
if (!node_fs.existsSync(outputPackageJSONPath)) {
|
|
277
|
+
throw new Error(
|
|
278
|
+
`${outputPackageJSONPath} 文件不存在,请检查 sources.packageJSON 配置是否正确`
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
const pkgContent = JSON.parse(node_fs.readFileSync(outputPackageJSONPath, "utf-8"));
|
|
282
|
+
const currentVersion = pkgContent.version;
|
|
283
|
+
const changes = await parseChangelog({
|
|
284
|
+
filePath: r(configs.changelogsPath),
|
|
285
|
+
removeMarkdown: false
|
|
286
|
+
});
|
|
287
|
+
const currentChange = changes.versions.find((change) => {
|
|
288
|
+
return change.version === currentVersion;
|
|
289
|
+
});
|
|
290
|
+
if (!currentChange) {
|
|
291
|
+
throw new Error(
|
|
292
|
+
`无法在 ${configs.changelogsPath} 中找到当前版本 ${currentVersion} 的记录,请检查是否按正确格式编写 changelog!`
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
const { date, version, title, body } = currentChange;
|
|
296
|
+
if (body.trim().length === 0) {
|
|
297
|
+
throw new Error(`当前版本 ${currentVersion} 的 Changelog 记录为空!`);
|
|
298
|
+
}
|
|
299
|
+
const window = new jsdom.JSDOM("").window;
|
|
300
|
+
const purify = DOMPurify(window);
|
|
301
|
+
const html = purify.sanitize(
|
|
302
|
+
marked.marked.parse(body, {
|
|
303
|
+
mangle: false,
|
|
304
|
+
headerIds: false
|
|
305
|
+
})
|
|
306
|
+
);
|
|
307
|
+
node_fs.writeFileSync(
|
|
308
|
+
r("node_modules/.evd/changelog.json"),
|
|
309
|
+
JSON.stringify({
|
|
310
|
+
title,
|
|
311
|
+
version,
|
|
312
|
+
date,
|
|
313
|
+
changes: html
|
|
314
|
+
}),
|
|
315
|
+
"utf-8"
|
|
316
|
+
);
|
|
317
|
+
console.log(
|
|
318
|
+
logSymbols.success,
|
|
319
|
+
`写入 changelog.json 成功 ${r("node_modules/.evd/changelog.json")}`
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
async function compile(configs) {
|
|
323
|
+
console.log(logSymbols.info, "开始编译", r());
|
|
324
|
+
node_child_process.execSync(`npm run ${configs.compileCommand}`, {
|
|
325
|
+
stdio: "inherit",
|
|
326
|
+
cwd: r()
|
|
327
|
+
});
|
|
328
|
+
console.log(logSymbols.success, "编译成功!");
|
|
329
|
+
if (!node_fs.existsSync(configs.sources.folder)) {
|
|
330
|
+
throw new Error(
|
|
331
|
+
`无法找到资源目录, ${configs.sources.folder} 请检查配置是否正确!`
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
function genTmpFolder() {
|
|
336
|
+
const folderPath = r("node_modules/.evd");
|
|
337
|
+
if (!node_fs.existsSync(folderPath))
|
|
338
|
+
node_fs.mkdirSync(folderPath);
|
|
339
|
+
}
|
|
340
|
+
function fetchRemotePkgJSON(remote_url) {
|
|
341
|
+
return new Promise((res, rej) => {
|
|
342
|
+
node_https.get(`${remote_url}/package.json`, (_res) => {
|
|
343
|
+
let data = "";
|
|
344
|
+
_res.on("data", (chunk) => {
|
|
345
|
+
data += chunk;
|
|
346
|
+
});
|
|
347
|
+
_res.on("end", () => {
|
|
348
|
+
try {
|
|
349
|
+
res(JSON.parse(data));
|
|
350
|
+
} catch (e) {
|
|
351
|
+
res(null);
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}).on("error", (err) => {
|
|
355
|
+
rej(`自动更新检查请求失败:` + err.toString());
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
function versionToNum(a) {
|
|
360
|
+
let c = a.split(".");
|
|
361
|
+
let num_place = ["", "0", "00", "000", "0000"], r2 = num_place.reverse();
|
|
362
|
+
for (let i = 0; i < c.length; i++) {
|
|
363
|
+
let len = c[i].length;
|
|
364
|
+
c[i] = r2[len] + c[i];
|
|
365
|
+
}
|
|
366
|
+
let res = c.join("");
|
|
367
|
+
return res;
|
|
368
|
+
}
|
|
369
|
+
commander.program.command("deploy").description("执行部署").action(async (source, destination) => {
|
|
370
|
+
const configs = await getConfigs();
|
|
371
|
+
try {
|
|
372
|
+
await checkEVDFolderExist();
|
|
373
|
+
await validateConfigs(configs);
|
|
374
|
+
await checkIsFirstTimeDeploy(configs);
|
|
375
|
+
await validateRemotePackageJSON(configs);
|
|
376
|
+
await deploy(configs);
|
|
377
|
+
} catch (e) {
|
|
378
|
+
console.log(logSymbols.error, e.toString());
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
async function deploy(configs) {
|
|
382
|
+
console.log(logSymbols.info, "开始部署", r());
|
|
383
|
+
const output = node_child_process.spawn("netlify", [
|
|
384
|
+
"deploy",
|
|
385
|
+
"--dir",
|
|
386
|
+
r("node_modules/.evd"),
|
|
387
|
+
"--site",
|
|
388
|
+
configs.netlify.siteID,
|
|
389
|
+
"--auth",
|
|
390
|
+
configs.netlify.token,
|
|
391
|
+
"--prod",
|
|
392
|
+
"--debug"
|
|
393
|
+
], {
|
|
394
|
+
stdio: ["pipe", "inherit", "inherit"]
|
|
395
|
+
});
|
|
396
|
+
output.on("exit", function(code) {
|
|
397
|
+
if (code === 0) {
|
|
398
|
+
console.log(logSymbols.success, "部署完成!");
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
throw new Error("部署失败!");
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
async function validateRemotePackageJSON(configs) {
|
|
405
|
+
const compiledPackageJSON = JSON.parse(
|
|
406
|
+
node_fs.readFileSync(r("node_modules/.evd/package.json"), "utf-8")
|
|
407
|
+
);
|
|
408
|
+
const compiledName = compiledPackageJSON.name;
|
|
409
|
+
const remotePKG = await fetchRemotePkgJSON(configs.netlify.url);
|
|
410
|
+
if (!remotePKG)
|
|
411
|
+
return;
|
|
412
|
+
const remoteName = remotePKG.name;
|
|
413
|
+
if (compiledName !== remoteName) {
|
|
414
|
+
const answer = await prompts.confirm({
|
|
415
|
+
message: `检测到项目名称不一致,确定继续吗 编译后的项目名称: ${compiledName}, 远程 package.json 中的项目名称 ${remoteName}`
|
|
416
|
+
});
|
|
417
|
+
if (!answer)
|
|
418
|
+
throw new Error(`部署已停止`);
|
|
419
|
+
const answerDoubleCheck = await prompts.confirm({
|
|
420
|
+
message: `确定继续执行吗?这将会覆盖远程的版本!`
|
|
421
|
+
});
|
|
422
|
+
if (!answerDoubleCheck)
|
|
423
|
+
throw new Error(`部署已停止`);
|
|
424
|
+
}
|
|
425
|
+
const localVersion = versionToNum(compiledPackageJSON.version);
|
|
426
|
+
const remoteVersion = versionToNum(remotePKG.version);
|
|
427
|
+
if (localVersion == remoteVersion) {
|
|
428
|
+
const answer = await prompts.confirm({
|
|
429
|
+
message: `检测到远程部署版本和当前版本一致 ${remotePKG.version},确定要覆盖部署吗?`
|
|
430
|
+
});
|
|
431
|
+
if (!answer)
|
|
432
|
+
throw new Error(`部署已停止`);
|
|
433
|
+
} else if (remoteVersion > localVersion) {
|
|
434
|
+
const answer = await prompts.confirm({
|
|
435
|
+
message: `检测到远程部署版本为 ${remotePKG.version} 大于当前版本 ${compiledPackageJSON.version},确定要覆盖部署吗?`
|
|
436
|
+
});
|
|
437
|
+
if (!answer)
|
|
438
|
+
throw new Error(`部署已停止`);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
async function checkIsFirstTimeDeploy(configs) {
|
|
442
|
+
const remotePKG = await fetchRemotePkgJSON(configs.netlify.url);
|
|
443
|
+
if (!remotePKG) {
|
|
444
|
+
const answer = await prompts.confirm({
|
|
445
|
+
message: `似乎 ${configs.netlify.url} 还未部署过任何版本,确认继续吗?`
|
|
446
|
+
});
|
|
447
|
+
if (!answer) {
|
|
448
|
+
throw new Error("部署已停止!");
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
async function validateConfigs(configs) {
|
|
453
|
+
if (!configs.netlify.url || !/^https/.test(configs.netlify.url)) {
|
|
454
|
+
throw new Error(`configs.netlify.url 配置不正确`);
|
|
455
|
+
}
|
|
456
|
+
if (!configs.netlify.token) {
|
|
457
|
+
throw new Error(`configs.netlify.token 未配置`);
|
|
458
|
+
}
|
|
459
|
+
if (!configs.netlify.siteID) {
|
|
460
|
+
throw new Error(`configs.netlify.siteID 未配置`);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
async function checkEVDFolderExist() {
|
|
464
|
+
if (!node_fs.existsSync(r("node_modules/.evd"))) {
|
|
465
|
+
throw new Error(`未找到 .evd 文件夹,你需要先执行 evd prepare`);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
commander.program.command("install-prebuilt").description("安装与构建包").action(async (source, destination) => {
|
|
469
|
+
const configs = await getConfigs();
|
|
470
|
+
if (configs.prebuiltConfig && Object.values(configs.prebuiltConfig).length > 0) {
|
|
471
|
+
await installPrebuilt(configs);
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
async function installPrebuilt(configs) {
|
|
475
|
+
Object.entries(configs.prebuiltConfig).map(async ([moduleName, config]) => {
|
|
476
|
+
const projectFolder = require.resolve(moduleName).split("node_modules")[0];
|
|
477
|
+
const pkgFolder = node_path.join(projectFolder, "node_modules", moduleName);
|
|
478
|
+
const pkgJSON = JSON.parse(
|
|
479
|
+
node_fs.readFileSync(node_path.join(pkgFolder, "package.json"), "utf-8")
|
|
480
|
+
);
|
|
481
|
+
const pkgVersion = pkgJSON.version;
|
|
482
|
+
const hostUrl = pkgJSON.binary.host;
|
|
483
|
+
const outputFolder = node_path.join(pkgFolder, ...config.outputPath);
|
|
484
|
+
for (let j = 0; j < config.files.length; j++) {
|
|
485
|
+
const downloadURL = `${hostUrl}v${pkgVersion}/${config.files[j]}`;
|
|
486
|
+
const outputPath = node_path.join(outputFolder);
|
|
487
|
+
await download(downloadURL, outputPath, {
|
|
488
|
+
extract: true
|
|
489
|
+
});
|
|
490
|
+
console.log(logSymbols.success, `下载: ${downloadURL} 成功!`);
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
commander.program.description(
|
|
495
|
+
"Electron 版本部署 CLI,简化你的 Electron 软件更新,让一切变得简单。"
|
|
496
|
+
).helpOption("-h, --help", "使用帮助").version("0.0.1", "-V, --version", "显示版本号").parse(process.argv);
|
package/dist/const.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const CLI_NAME = "electron-version-deployer-cli";
|
|
4
|
+
const CONFIG_FILE_NAME = "evd.config.js";
|
|
5
|
+
function defineEVDConfig(configs) {
|
|
6
|
+
return configs;
|
|
7
|
+
}
|
|
8
|
+
exports.CLI_NAME = CLI_NAME;
|
|
9
|
+
exports.CONFIG_FILE_NAME = CONFIG_FILE_NAME;
|
|
10
|
+
exports.defineEVDConfig = defineEVDConfig;
|
package/dist/index.d.ts
ADDED