cli-z-develop 0.16.4 → 0.16.6
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/index.js +710 -703
- package/package.json +25 -25
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { program as
|
|
1
|
+
import { program as x } from "commander";
|
|
2
2
|
import Yt from "node:child_process";
|
|
3
|
-
import { existsSync as j, readdirSync as Xt, lstatSync as Qt, createWriteStream as ea, writeFileSync as ve, readFileSync as dt, mkdirSync as ta, mkdtempSync as aa, rmSync as
|
|
4
|
-
import { readdir as Ue, mkdir as fe, writeFile as
|
|
3
|
+
import { existsSync as j, readdirSync as Xt, lstatSync as Qt, createWriteStream as ea, writeFileSync as ve, readFileSync as dt, mkdirSync as ta, mkdtempSync as aa, rmSync as sa } from "node:fs";
|
|
4
|
+
import { readdir as Ue, mkdir as fe, writeFile as z, rename as ft, readFile as _e, stat as na } from "node:fs/promises";
|
|
5
5
|
import f, { resolve as pe, isAbsolute as ia, normalize as ra, sep as oa } from "node:path";
|
|
6
6
|
import me, { AxiosError as gt } from "axios";
|
|
7
7
|
import A from "chalk";
|
|
@@ -9,9 +9,9 @@ import ca from "dayjs";
|
|
|
9
9
|
import N from "shelljs";
|
|
10
10
|
import la, { tmpdir as ua } from "node:os";
|
|
11
11
|
import tt from "child_process";
|
|
12
|
-
import { confirm as Le, select as E, input as
|
|
12
|
+
import { confirm as Le, select as E, input as _, password as pa, checkbox as Re, number as at } from "@inquirer/prompts";
|
|
13
13
|
import y from "ora";
|
|
14
|
-
import
|
|
14
|
+
import C from "fs-extra";
|
|
15
15
|
import ma from "open";
|
|
16
16
|
import { select as V } from "inquirer-select-pro";
|
|
17
17
|
import da from "lint-staged";
|
|
@@ -24,23 +24,23 @@ import { ESLint as wt } from "eslint";
|
|
|
24
24
|
import Sa from "prettier";
|
|
25
25
|
import Na from "minimist";
|
|
26
26
|
const yt = "dev", $t = "test", vt = "release", ja = "production", Ta = "master";
|
|
27
|
-
var
|
|
27
|
+
var D = /* @__PURE__ */ ((e) => (e[e.DEV = yt] = "DEV", e[e.TEST = $t] = "TEST", e[e.RELEASE = vt] = "RELEASE", e[e.PROD = ja] = "PROD", e))(D || {}), w = /* @__PURE__ */ ((e) => (e[e.DEV = yt] = "DEV", e[e.TEST = $t] = "TEST", e[e.RELEASE = vt] = "RELEASE", e[e.MASTER = Ta] = "MASTER", e))(w || {}), Y = /* @__PURE__ */ ((e) => (e.H5 = "h5", e.NPM = "npm", e.SERVER = "server", e))(Y || {});
|
|
28
28
|
const At = [
|
|
29
29
|
{
|
|
30
|
-
name: `开发环境 - ${
|
|
31
|
-
value:
|
|
30
|
+
name: `开发环境 - ${D.DEV}`,
|
|
31
|
+
value: D.DEV
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
|
-
name: `测试环境 - ${
|
|
35
|
-
value:
|
|
34
|
+
name: `测试环境 - ${D.TEST}`,
|
|
35
|
+
value: D.TEST
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
|
-
name: `预发环境 - ${
|
|
39
|
-
value:
|
|
38
|
+
name: `预发环境 - ${D.RELEASE}`,
|
|
39
|
+
value: D.RELEASE
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
|
-
name: `正式环境 - ${
|
|
43
|
-
value:
|
|
42
|
+
name: `正式环境 - ${D.PROD}`,
|
|
43
|
+
value: D.PROD
|
|
44
44
|
}
|
|
45
45
|
], ka = [
|
|
46
46
|
{
|
|
@@ -73,7 +73,7 @@ const Ea = {
|
|
|
73
73
|
}, Ae = "http://git.cxlqd.com", Ia = ["fe-biz", "fe-base", "fe-tpl", "fe-component", "fe-demo"];
|
|
74
74
|
var T = /* @__PURE__ */ ((e) => (e.FEAT = "feat", e.FIX = "fix", e.REFACTOR = "refactor", e.CHORE = "chore", e.CI = "ci", e.Break = "BREAKING CHANGE", e))(T || {});
|
|
75
75
|
const Ra = "fe-biz7tvsd", bt = "https://hxhtbr8t8uy.feishu.cn/wiki/LWW5wAQFPiXkmRkKcjOcyDDknLg";
|
|
76
|
-
var
|
|
76
|
+
var R = /* @__PURE__ */ ((e) => (e.MODULE = "module", e.CASE = "case", e))(R || {});
|
|
77
77
|
const Ca = [
|
|
78
78
|
{
|
|
79
79
|
name: "模块",
|
|
@@ -85,18 +85,18 @@ const Ca = [
|
|
|
85
85
|
value: "case"
|
|
86
86
|
/* CASE */
|
|
87
87
|
}
|
|
88
|
-
], La = 150 * 1024,
|
|
89
|
-
function
|
|
88
|
+
], La = 150 * 1024, st = 0.8 * 1024 * 1024, Fe = ",", xa = ".z", Pa = "develop-config.json", K = ".z", Da = ".commit-msg-tpl", Oa = "project.json";
|
|
89
|
+
function L(e = "") {
|
|
90
90
|
return f.join(K, e);
|
|
91
91
|
}
|
|
92
92
|
function St() {
|
|
93
|
-
return
|
|
93
|
+
return L(Oa);
|
|
94
94
|
}
|
|
95
95
|
function Se() {
|
|
96
|
-
return
|
|
96
|
+
return L(Da);
|
|
97
97
|
}
|
|
98
98
|
function Nt() {
|
|
99
|
-
tt.spawnSync("git", ["config", "core.hooksPath",
|
|
99
|
+
tt.spawnSync("git", ["config", "core.hooksPath", L()]), tt.spawnSync("git", ["config", "commit.template", Se()]);
|
|
100
100
|
}
|
|
101
101
|
function Ne(e = "") {
|
|
102
102
|
return f.resolve(la.homedir(), xa, e);
|
|
@@ -110,22 +110,22 @@ function Ma() {
|
|
|
110
110
|
function jt() {
|
|
111
111
|
return Ma() && j(xe());
|
|
112
112
|
}
|
|
113
|
-
function
|
|
113
|
+
function se(e, t = !0) {
|
|
114
114
|
let a = e.trim();
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
117
|
-
a =
|
|
115
|
+
const n = a.match(/^git@([^:]+):(.+)$/);
|
|
116
|
+
if (n)
|
|
117
|
+
a = n[2];
|
|
118
118
|
else {
|
|
119
119
|
const i = Ae.replace(/^https?:\/\//, "").replace(/\/$/, "");
|
|
120
120
|
a = a.replace(/^https?:\/\//, ""), a.startsWith(`${i}/`) ? a = a.slice(i.length + 1) : a = a.replace(`${Ae.replace(/\/$/, "")}/`, "");
|
|
121
121
|
}
|
|
122
|
-
const
|
|
123
|
-
return t ? encodeURIComponent(
|
|
122
|
+
const s = a.replace(/\.git$/, "");
|
|
123
|
+
return t ? encodeURIComponent(s) : s;
|
|
124
124
|
}
|
|
125
125
|
function Pe(e, t) {
|
|
126
|
-
return
|
|
126
|
+
return se(e) === se(t);
|
|
127
127
|
}
|
|
128
|
-
const { red:
|
|
128
|
+
const { red: nt, green: Ba, blue: Ar, magenta: za, yellow: _a } = A;
|
|
129
129
|
function Te(...e) {
|
|
130
130
|
}
|
|
131
131
|
function J(...e) {
|
|
@@ -138,9 +138,12 @@ function Tt(e) {
|
|
|
138
138
|
e instanceof Error && (e.name === "ExitPromptError" || e.message.includes("User force closed the prompt with")) && (console.log(), console.log(A.cyan(" 👋 下次见~")), console.log(), process.exit(1));
|
|
139
139
|
}
|
|
140
140
|
function m(e, t = !1) {
|
|
141
|
-
Tt(e)
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
if (Tt(e), e instanceof Error) {
|
|
142
|
+
const a = me.isAxiosError(e) ? `请求失败:${e.message}` : e.message;
|
|
143
|
+
console.log(nt(a)), console.log(za(e.stack));
|
|
144
|
+
} else
|
|
145
|
+
console.log(nt(e));
|
|
146
|
+
t || process.exit(1);
|
|
144
147
|
}
|
|
145
148
|
function it(e) {
|
|
146
149
|
return j(e) ? Qt(e).isDirectory() : !1;
|
|
@@ -154,17 +157,17 @@ async function p(e, t = {}) {
|
|
|
154
157
|
silent: !0,
|
|
155
158
|
...t
|
|
156
159
|
};
|
|
157
|
-
let
|
|
160
|
+
let n = await new Promise((s, i) => {
|
|
158
161
|
try {
|
|
159
162
|
const o = N.exec(e, {
|
|
160
163
|
silent: a.silent
|
|
161
164
|
});
|
|
162
|
-
|
|
165
|
+
s(o);
|
|
163
166
|
} catch (o) {
|
|
164
167
|
i(o);
|
|
165
168
|
}
|
|
166
169
|
});
|
|
167
|
-
return
|
|
170
|
+
return n = n.toString(), a.removeTailLinkBreak && (n = n.replace(/\n$/, "")), n;
|
|
168
171
|
}
|
|
169
172
|
function Ve(e) {
|
|
170
173
|
Yt.execSync(e, {
|
|
@@ -175,7 +178,7 @@ function Et() {
|
|
|
175
178
|
return ca(Date.now()).format("YYMMDD");
|
|
176
179
|
}
|
|
177
180
|
function ee() {
|
|
178
|
-
j(
|
|
181
|
+
j(L()) || m("当前不在项目根目录。请切换到项目根目录");
|
|
179
182
|
}
|
|
180
183
|
function H() {
|
|
181
184
|
j(f.resolve(".git")) || m("当前不是git项目根目录,请先执行git init,或切换到根目录");
|
|
@@ -184,12 +187,12 @@ async function ge() {
|
|
|
184
187
|
await p("git status -s") !== "" && m("请先提交代码变动,再进行操作");
|
|
185
188
|
}
|
|
186
189
|
function Fa(e) {
|
|
187
|
-
return e === w.MASTER ?
|
|
190
|
+
return e === w.MASTER ? D.PROD : e;
|
|
188
191
|
}
|
|
189
192
|
function Ga(e) {
|
|
190
|
-
return e ===
|
|
193
|
+
return e === D.PROD ? w.MASTER : e;
|
|
191
194
|
}
|
|
192
|
-
async function
|
|
195
|
+
async function M(e, ...t) {
|
|
193
196
|
try {
|
|
194
197
|
await e(...t);
|
|
195
198
|
} catch (a) {
|
|
@@ -274,7 +277,7 @@ const Va = {
|
|
|
274
277
|
"**/*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}": "eslint --fix",
|
|
275
278
|
"**/*.md": "markdownlint --fix"
|
|
276
279
|
}
|
|
277
|
-
}, Wa = "cli-z-develop", Ha = "0.16.
|
|
280
|
+
}, Wa = "cli-z-develop", Ha = "0.16.6", qa = "技术团队开发流程管理工具", Za = "dist/index.js", Ka = { z: "bin/z.js", "z-develop": "bin/z.js" }, Ya = { prepare: "[ -n '$z' ] && z init prepare || echo 'Warning: z not exist at global'", dev: "vite build --watch", test: "bun src/main.ts", "test:debug": "DEBUG=true bun src/main.ts", "dev:debug": "DEBUG=true vite build --watch", build: "vite build", "build:w": "vite build --watch", eslint: "eslint '**/*.{ts,js}' --fix", prettier: "prettier -wu .", upload: "npm run build && npm publish --access public --registry https://registry.npmjs.org/", "upload:patch": "npm version patch && npm run upload", "upload:minor": "npm version minor && npm run upload", "upload:major": "npm version major && npm run upload" }, Xa = "module", Qa = "z", es = { "@lonely9/eslint-config-team": "^1.4.0", "@tsconfig/node22": "^22.0.6", "@types/fs-extra": "^11.0.4", "@types/inquirer": "^9.0.10", "@types/minimist": "^1.2.5", "@types/node": "^22.15.29", "@types/semver": "^7.8.0", "@types/shelljs": "^0.10.0", "@typescript-eslint/eslint-plugin": "^8.70.0", "@typescript-eslint/parser": "^8.70.0", eslint: "^10.10.0", jiti: "^2.7.0", prettier: "^3.9.8", typescript: "^5.9.3", vite: "^7.3.1", "vue-tsc": "^3.3.11" }, ts = { "@inquirer/prompts": "^8.7.2", "@lonely9/api-generate": "^0.2.13", axios: "^1.20.0", chalk: "^6.0.0", "cli-highlight": "^2.1.11", commander: "^15.0.0", dayjs: "^1.11.23", eslint: "^10.10.0", "fs-extra": "^11.4.0", "inquirer-select-pro": "^1.0.0-alpha.9", "lint-staged": "^17.5.1", minimist: "^1.2.8", "npm-check-updates": "^23.1.0", open: "^11.0.4", ora: "^9.4.1", "p-limit": "^7.3.2", prettier: "^3.9.8", semver: "^7.8.5", shelljs: "^0.10.0" }, ce = {
|
|
278
281
|
name: Wa,
|
|
279
282
|
version: Ha,
|
|
280
283
|
description: qa,
|
|
@@ -283,9 +286,9 @@ const Va = {
|
|
|
283
286
|
scripts: Ya,
|
|
284
287
|
type: Xa,
|
|
285
288
|
author: Qa,
|
|
286
|
-
devDependencies:
|
|
287
|
-
dependencies:
|
|
288
|
-
},
|
|
289
|
+
devDependencies: es,
|
|
290
|
+
dependencies: ts
|
|
291
|
+
}, O = {
|
|
289
292
|
// 个人数据
|
|
290
293
|
profile: {
|
|
291
294
|
ldapAccount: "",
|
|
@@ -320,20 +323,20 @@ const Va = {
|
|
|
320
323
|
}
|
|
321
324
|
};
|
|
322
325
|
function I(e) {
|
|
323
|
-
return e ?
|
|
326
|
+
return e ? O.profile[e] : O.profile;
|
|
324
327
|
}
|
|
325
328
|
function be(e) {
|
|
326
|
-
return e ?
|
|
329
|
+
return e ? O.main[e] : O.main;
|
|
327
330
|
}
|
|
328
331
|
function re(e) {
|
|
329
|
-
return e ?
|
|
332
|
+
return e ? O.constants[e] : O.constants;
|
|
330
333
|
}
|
|
331
334
|
let q = null, Z = null;
|
|
332
335
|
function We() {
|
|
333
336
|
if (q)
|
|
334
337
|
return q;
|
|
335
338
|
const e = f.join("package.json");
|
|
336
|
-
return j(e) || m(`当前目录(${N.pwd()})不存在${e}文件,请在项目根目录执行该命令。`), q =
|
|
339
|
+
return j(e) || m(`当前目录(${N.pwd()})不存在${e}文件,请在项目根目录执行该命令。`), q = C.readJsonSync(e), q;
|
|
337
340
|
}
|
|
338
341
|
function W() {
|
|
339
342
|
if (Z)
|
|
@@ -341,19 +344,19 @@ function W() {
|
|
|
341
344
|
const e = St();
|
|
342
345
|
return j(e) || m(
|
|
343
346
|
`当前目录(${N.pwd()})不存在${e}文件,请在项目根目录执行该命令,或者初始化项目(z init .)。`
|
|
344
|
-
), Z =
|
|
347
|
+
), Z = C.readJsonSync(e), Z;
|
|
345
348
|
}
|
|
346
349
|
function It(e) {
|
|
347
350
|
Z ? Z = {
|
|
348
351
|
...Z,
|
|
349
352
|
...e
|
|
350
|
-
} : Z = e,
|
|
353
|
+
} : Z = e, C.writeJSONSync(St(), Z, { spaces: 2 });
|
|
351
354
|
}
|
|
352
|
-
function
|
|
355
|
+
function as(e) {
|
|
353
356
|
q ? q = {
|
|
354
357
|
...q,
|
|
355
358
|
...e
|
|
356
|
-
} : q = e,
|
|
359
|
+
} : q = e, C.writeJSONSync(f.join("package.json"), q, { spaces: 2 });
|
|
357
360
|
}
|
|
358
361
|
const ae = {
|
|
359
362
|
id: 0,
|
|
@@ -362,10 +365,10 @@ const ae = {
|
|
|
362
365
|
sourceBranch: "",
|
|
363
366
|
mergeRequestUrl: ""
|
|
364
367
|
};
|
|
365
|
-
async function
|
|
368
|
+
async function ss() {
|
|
366
369
|
if (!ae.id)
|
|
367
370
|
try {
|
|
368
|
-
const e = W(), t =
|
|
371
|
+
const e = W(), t = se(e.repository.url), a = await Lt(t);
|
|
369
372
|
ae.id = a.id, ae.path = t, ae.group = a.namespace.full_path, ae.mergeRequestUrl = `${a.web_url}/merge_requests`;
|
|
370
373
|
} catch (e) {
|
|
371
374
|
m(e);
|
|
@@ -373,7 +376,7 @@ async function nn() {
|
|
|
373
376
|
return ae.sourceBranch || (ae.sourceBranch = await p("git branch --show-current")), ae;
|
|
374
377
|
}
|
|
375
378
|
function X() {
|
|
376
|
-
|
|
379
|
+
C.writeJSONSync(
|
|
377
380
|
xe(),
|
|
378
381
|
{
|
|
379
382
|
main: be(),
|
|
@@ -386,25 +389,25 @@ function X() {
|
|
|
386
389
|
);
|
|
387
390
|
}
|
|
388
391
|
function k(e, t) {
|
|
389
|
-
t !== void 0 ?
|
|
390
|
-
...
|
|
392
|
+
t !== void 0 ? O.profile[e] = t : O.profile = {
|
|
393
|
+
...O.profile,
|
|
391
394
|
...e
|
|
392
395
|
};
|
|
393
396
|
}
|
|
394
397
|
function De(e, t) {
|
|
395
|
-
|
|
396
|
-
...
|
|
398
|
+
O.constants = {
|
|
399
|
+
...O.constants,
|
|
397
400
|
...e
|
|
398
401
|
};
|
|
399
402
|
}
|
|
400
403
|
function de(e, t) {
|
|
401
|
-
t !== void 0 ?
|
|
402
|
-
...
|
|
404
|
+
t !== void 0 ? O.main[e] = t : O.main = {
|
|
405
|
+
...O.main,
|
|
403
406
|
...e
|
|
404
407
|
};
|
|
405
408
|
}
|
|
406
409
|
async function b(e) {
|
|
407
|
-
const t = await
|
|
410
|
+
const t = await ne({
|
|
408
411
|
url: "https://pai.zxfqf.com/api" + e.url,
|
|
409
412
|
headers: {
|
|
410
413
|
"the-key-one": "z-develop",
|
|
@@ -415,8 +418,8 @@ async function b(e) {
|
|
|
415
418
|
});
|
|
416
419
|
return t.code !== 0 && (m(`${t.code}: ${t.message}`, e.stopBubble), e.stopBubble) ? Promise.reject(t) : t.data;
|
|
417
420
|
}
|
|
418
|
-
async function
|
|
419
|
-
return await
|
|
421
|
+
async function ns(e) {
|
|
422
|
+
return await ne({
|
|
420
423
|
url: "https://pai.zxfqf.com/api" + e.url,
|
|
421
424
|
headers: {
|
|
422
425
|
"the-key-one": "z-develop",
|
|
@@ -426,12 +429,12 @@ async function sn(e) {
|
|
|
426
429
|
method: e.method || "post"
|
|
427
430
|
});
|
|
428
431
|
}
|
|
429
|
-
function
|
|
432
|
+
function is() {
|
|
430
433
|
return b({
|
|
431
434
|
url: "/user/list2"
|
|
432
435
|
});
|
|
433
436
|
}
|
|
434
|
-
function
|
|
437
|
+
function rs() {
|
|
435
438
|
return b({
|
|
436
439
|
url: "/zen/testcase/product/list"
|
|
437
440
|
});
|
|
@@ -444,7 +447,7 @@ function Rt(e) {
|
|
|
444
447
|
}
|
|
445
448
|
});
|
|
446
449
|
}
|
|
447
|
-
function
|
|
450
|
+
function os(e) {
|
|
448
451
|
return b({
|
|
449
452
|
url: "/zen/testcase/product/name",
|
|
450
453
|
data: {
|
|
@@ -452,7 +455,7 @@ function cn(e) {
|
|
|
452
455
|
}
|
|
453
456
|
});
|
|
454
457
|
}
|
|
455
|
-
function
|
|
458
|
+
function cs(e, t) {
|
|
456
459
|
return b({
|
|
457
460
|
url: "/zen/testcase/product/auto-case/list",
|
|
458
461
|
data: {
|
|
@@ -461,7 +464,7 @@ function ln(e, t) {
|
|
|
461
464
|
}
|
|
462
465
|
});
|
|
463
466
|
}
|
|
464
|
-
function
|
|
467
|
+
function ls(e) {
|
|
465
468
|
return b({
|
|
466
469
|
url: "/zen/testcase/step/list",
|
|
467
470
|
data: {
|
|
@@ -469,72 +472,72 @@ function un(e) {
|
|
|
469
472
|
}
|
|
470
473
|
});
|
|
471
474
|
}
|
|
472
|
-
function
|
|
475
|
+
function us(e) {
|
|
473
476
|
return b({
|
|
474
477
|
url: "/zen/testcase/module/create",
|
|
475
478
|
data: e
|
|
476
479
|
});
|
|
477
480
|
}
|
|
478
|
-
function
|
|
481
|
+
function ps(e) {
|
|
479
482
|
return b({
|
|
480
483
|
url: "/zen/testcase/create",
|
|
481
484
|
data: e
|
|
482
485
|
});
|
|
483
486
|
}
|
|
484
|
-
function
|
|
487
|
+
function ms(e) {
|
|
485
488
|
return b({
|
|
486
489
|
url: "/zen/testcase/step/create",
|
|
487
490
|
data: e
|
|
488
491
|
});
|
|
489
492
|
}
|
|
490
|
-
function
|
|
493
|
+
function ds(e) {
|
|
491
494
|
return b({
|
|
492
495
|
url: "/zen/testcase/modules/remove",
|
|
493
496
|
data: e
|
|
494
497
|
});
|
|
495
498
|
}
|
|
496
|
-
function
|
|
499
|
+
function fs(e) {
|
|
497
500
|
return b({
|
|
498
501
|
url: "/zen/testcase/cases/remove",
|
|
499
502
|
data: e
|
|
500
503
|
});
|
|
501
504
|
}
|
|
502
|
-
function
|
|
505
|
+
function gs(e) {
|
|
503
506
|
return b({
|
|
504
507
|
url: "/zen/testcase/module/update/name",
|
|
505
508
|
data: e
|
|
506
509
|
});
|
|
507
510
|
}
|
|
508
|
-
function
|
|
511
|
+
function hs(e) {
|
|
509
512
|
return b({
|
|
510
513
|
url: "/zen/testcase/case/update/name",
|
|
511
514
|
data: e
|
|
512
515
|
});
|
|
513
516
|
}
|
|
514
|
-
function
|
|
517
|
+
function ws(e) {
|
|
515
518
|
return b({
|
|
516
519
|
url: "/zen/testcase/case/update/priority",
|
|
517
520
|
data: e
|
|
518
521
|
});
|
|
519
522
|
}
|
|
520
|
-
function
|
|
523
|
+
function ys(e) {
|
|
521
524
|
return b({
|
|
522
525
|
url: "/zen/testcase/case/update/precondition",
|
|
523
526
|
data: e
|
|
524
527
|
});
|
|
525
528
|
}
|
|
526
|
-
function
|
|
529
|
+
function $s(e) {
|
|
527
530
|
return b({
|
|
528
531
|
url: "/zen/testcase/case/result/create",
|
|
529
532
|
data: e
|
|
530
533
|
});
|
|
531
534
|
}
|
|
532
|
-
function
|
|
535
|
+
function vs() {
|
|
533
536
|
return b({
|
|
534
537
|
url: "/zen/testcase/project/list"
|
|
535
538
|
});
|
|
536
539
|
}
|
|
537
|
-
function
|
|
540
|
+
function As(e) {
|
|
538
541
|
return b({
|
|
539
542
|
url: "/zen/testcase/project/execution/list",
|
|
540
543
|
data: {
|
|
@@ -542,7 +545,7 @@ function bn(e) {
|
|
|
542
545
|
}
|
|
543
546
|
});
|
|
544
547
|
}
|
|
545
|
-
function
|
|
548
|
+
function bs(e) {
|
|
546
549
|
return b({
|
|
547
550
|
url: "/zen/testcase/execution/build/list",
|
|
548
551
|
data: {
|
|
@@ -556,19 +559,19 @@ function rt(e) {
|
|
|
556
559
|
data: e
|
|
557
560
|
});
|
|
558
561
|
}
|
|
559
|
-
function
|
|
560
|
-
return
|
|
562
|
+
function Ss(e) {
|
|
563
|
+
return ns({
|
|
561
564
|
url: "/common/notify/group/send",
|
|
562
565
|
data: e
|
|
563
566
|
});
|
|
564
567
|
}
|
|
565
|
-
function
|
|
568
|
+
function Ns(e) {
|
|
566
569
|
return b({
|
|
567
570
|
url: "/deploy/create/chain",
|
|
568
571
|
data: e
|
|
569
572
|
});
|
|
570
573
|
}
|
|
571
|
-
function
|
|
574
|
+
function js(e) {
|
|
572
575
|
return b({
|
|
573
576
|
url: "/zen/product/execution/list",
|
|
574
577
|
data: {
|
|
@@ -576,18 +579,18 @@ function Tn(e) {
|
|
|
576
579
|
}
|
|
577
580
|
});
|
|
578
581
|
}
|
|
579
|
-
function
|
|
582
|
+
function Ts(e) {
|
|
580
583
|
return b({
|
|
581
584
|
url: "/zen/execution/build/createOrUpdate",
|
|
582
585
|
data: e
|
|
583
586
|
});
|
|
584
587
|
}
|
|
585
|
-
function
|
|
588
|
+
function ks() {
|
|
586
589
|
return b({
|
|
587
590
|
url: "/auth/gitlab/oauth/authorize"
|
|
588
591
|
});
|
|
589
592
|
}
|
|
590
|
-
function
|
|
593
|
+
function Es(e) {
|
|
591
594
|
return b({
|
|
592
595
|
url: "/auth/gitlab/oauth/token",
|
|
593
596
|
data: {
|
|
@@ -596,7 +599,7 @@ function In(e) {
|
|
|
596
599
|
stopBubble: !0
|
|
597
600
|
});
|
|
598
601
|
}
|
|
599
|
-
function
|
|
602
|
+
function Is(e) {
|
|
600
603
|
return b({
|
|
601
604
|
url: "/auth/gitlab/oauth/token/refresh",
|
|
602
605
|
data: {
|
|
@@ -605,7 +608,7 @@ function Rn(e) {
|
|
|
605
608
|
stopBubble: !0
|
|
606
609
|
});
|
|
607
610
|
}
|
|
608
|
-
class
|
|
611
|
+
class Rs {
|
|
609
612
|
/**
|
|
610
613
|
* 生成带 Bearer 前缀的 Token
|
|
611
614
|
*/
|
|
@@ -626,21 +629,21 @@ class Cn {
|
|
|
626
629
|
* @private
|
|
627
630
|
*/
|
|
628
631
|
async refreshAccessToken(t) {
|
|
629
|
-
const a = await
|
|
632
|
+
const a = await Is(t);
|
|
630
633
|
return this.saveToken(a), this.generateBearerToken(a.access_token, a.token_type);
|
|
631
634
|
}
|
|
632
635
|
/**
|
|
633
636
|
* 执行完整的 OAuth 授权流程
|
|
634
637
|
*/
|
|
635
638
|
async auth() {
|
|
636
|
-
const t = await
|
|
639
|
+
const t = await ks(), a = `${Ae}/oauth/authorize?${new URLSearchParams({
|
|
637
640
|
...t
|
|
638
641
|
})}`;
|
|
639
|
-
return console.log(A.cyan("正在打开浏览器进行 GitLab 授权,如果浏览器未自动打开,请访问: ")), console.log(A.blue(a)), new Promise((
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
}).catch((
|
|
643
|
-
m(`❌ GitLab 授权失败:${
|
|
642
|
+
return console.log(A.cyan("正在打开浏览器进行 GitLab 授权,如果浏览器未自动打开,请访问: ")), console.log(A.blue(a)), new Promise((n) => {
|
|
643
|
+
Es(t.state).then((s) => {
|
|
644
|
+
s ? (console.log(A.green("✅ GitLab 授权成功!")), this.saveToken(s), n(this.generateBearerToken(s.access_token, s.token_type))) : m("❌ GitLab 授权失败!");
|
|
645
|
+
}).catch((s) => {
|
|
646
|
+
m(`❌ GitLab 授权失败:${s.message}`);
|
|
644
647
|
}), ma(a);
|
|
645
648
|
});
|
|
646
649
|
}
|
|
@@ -655,28 +658,28 @@ class Cn {
|
|
|
655
658
|
const t = I("gitToken"), a = I("gitTokenExpiry");
|
|
656
659
|
if (t && a && Date.now() < a)
|
|
657
660
|
return t;
|
|
658
|
-
const
|
|
659
|
-
if (
|
|
661
|
+
const n = I("gitLabRefreshToken");
|
|
662
|
+
if (n)
|
|
660
663
|
try {
|
|
661
|
-
return await this.refreshAccessToken(
|
|
664
|
+
return await this.refreshAccessToken(n);
|
|
662
665
|
} catch {
|
|
663
666
|
console.log(A.yellow("⚠️ Token 刷新失败,需要重新授权")), k("gitToken", ""), k("gitLabRefreshToken", ""), k("gitTokenExpiry", ""), X();
|
|
664
667
|
}
|
|
665
668
|
return await this.auth();
|
|
666
669
|
}
|
|
667
670
|
}
|
|
668
|
-
const ot = new
|
|
669
|
-
async function
|
|
670
|
-
const t = e.method || "get", a = e.headers || {},
|
|
671
|
+
const ot = new Rs();
|
|
672
|
+
async function ne(e) {
|
|
673
|
+
const t = e.method || "get", a = e.headers || {}, n = e.data || {}, s = e.dataKey ?? (["GET", "get"].includes(t) ? "params" : "data");
|
|
671
674
|
try {
|
|
672
675
|
const i = {
|
|
673
676
|
url: e.url,
|
|
674
677
|
method: t,
|
|
675
|
-
[
|
|
678
|
+
[s]: n,
|
|
676
679
|
headers: a,
|
|
677
680
|
responseType: e?.responseType || "json"
|
|
678
681
|
};
|
|
679
|
-
Te(A.magenta(i.method.toUpperCase()), A.yellow(i.url), JSON.stringify(i.headers)), Te(A.gray(JSON.stringify(i[
|
|
682
|
+
Te(A.magenta(i.method.toUpperCase()), A.yellow(i.url), JSON.stringify(i.headers)), Te(A.gray(JSON.stringify(i[s], null, 2)));
|
|
680
683
|
const o = await me(i);
|
|
681
684
|
return Te(A.green("Response"), A.grey(JSON.stringify(o.data, null, 2))), Promise.resolve(o.data);
|
|
682
685
|
} catch (i) {
|
|
@@ -685,7 +688,7 @@ async function se(e) {
|
|
|
685
688
|
}
|
|
686
689
|
async function S(e) {
|
|
687
690
|
try {
|
|
688
|
-
return await
|
|
691
|
+
return await ne({
|
|
689
692
|
...e,
|
|
690
693
|
headers: {
|
|
691
694
|
Authorization: await ot.getToken()
|
|
@@ -693,7 +696,7 @@ async function S(e) {
|
|
|
693
696
|
});
|
|
694
697
|
} catch (t) {
|
|
695
698
|
if (t instanceof gt && t.response?.status === 401)
|
|
696
|
-
return console.log(A.yellow("⚠️ GitLab Token 已失效,正在重新授权...")), k("gitToken", ""), k("gitLabRefreshToken", ""), k("gitTokenExpiry", ""), X(),
|
|
699
|
+
return console.log(A.yellow("⚠️ GitLab Token 已失效,正在重新授权...")), k("gitToken", ""), k("gitLabRefreshToken", ""), k("gitTokenExpiry", ""), X(), ne({
|
|
697
700
|
...e,
|
|
698
701
|
headers: {
|
|
699
702
|
Authorization: await ot.getToken()
|
|
@@ -702,12 +705,12 @@ async function S(e) {
|
|
|
702
705
|
throw t;
|
|
703
706
|
}
|
|
704
707
|
}
|
|
705
|
-
async function
|
|
708
|
+
async function Cs() {
|
|
706
709
|
const e = I("zenTaoToken");
|
|
707
710
|
if (e)
|
|
708
711
|
return e;
|
|
709
712
|
{
|
|
710
|
-
const { token: t } = await
|
|
713
|
+
const { token: t } = await ne({
|
|
711
714
|
url: `${re("ZenTaoDomain")}/api.php/v1/tokens`,
|
|
712
715
|
method: "post",
|
|
713
716
|
data: {
|
|
@@ -719,10 +722,10 @@ async function Ln() {
|
|
|
719
722
|
}
|
|
720
723
|
}
|
|
721
724
|
async function Ce(e) {
|
|
722
|
-
const t = await
|
|
725
|
+
const t = await ne({
|
|
723
726
|
...e,
|
|
724
727
|
headers: {
|
|
725
|
-
Token: await
|
|
728
|
+
Token: await Cs()
|
|
726
729
|
}
|
|
727
730
|
});
|
|
728
731
|
if (e.url.includes("local")) {
|
|
@@ -735,22 +738,22 @@ async function Ce(e) {
|
|
|
735
738
|
...e
|
|
736
739
|
})) : t;
|
|
737
740
|
} else {
|
|
738
|
-
const { status: a, data:
|
|
741
|
+
const { status: a, data: n } = t;
|
|
739
742
|
if (a === "success") {
|
|
740
|
-
const
|
|
741
|
-
return
|
|
743
|
+
const s = JSON.parse(n);
|
|
744
|
+
return s.title === "用户登录" ? (k("zenTaoToken", ""), Ce({
|
|
742
745
|
...e
|
|
743
|
-
})) :
|
|
746
|
+
})) : s;
|
|
744
747
|
} else
|
|
745
748
|
return {};
|
|
746
749
|
}
|
|
747
750
|
}
|
|
748
|
-
async function
|
|
751
|
+
async function Ls() {
|
|
749
752
|
const e = I("k8sToken");
|
|
750
753
|
if (e)
|
|
751
754
|
return e;
|
|
752
755
|
{
|
|
753
|
-
const { access_token: t } = await
|
|
756
|
+
const { access_token: t } = await ne({
|
|
754
757
|
url: `${re("K8sDomain")}/oauth/login/LDAP`,
|
|
755
758
|
method: "post",
|
|
756
759
|
headers: {
|
|
@@ -764,7 +767,7 @@ async function xn() {
|
|
|
764
767
|
return k("k8sToken", a), X(), a;
|
|
765
768
|
}
|
|
766
769
|
}
|
|
767
|
-
async function
|
|
770
|
+
async function xs(e, t) {
|
|
768
771
|
try {
|
|
769
772
|
const a = ea(t, { mode: 493 });
|
|
770
773
|
return (await me({
|
|
@@ -774,222 +777,222 @@ async function Pn(e, t) {
|
|
|
774
777
|
headers: {
|
|
775
778
|
"Content-Type": "application/octet-stream"
|
|
776
779
|
}
|
|
777
|
-
})).data.pipe(a), new Promise((
|
|
778
|
-
a.on("finish", () =>
|
|
780
|
+
})).data.pipe(a), new Promise((s, i) => {
|
|
781
|
+
a.on("finish", () => s(1)), a.on("error", i);
|
|
779
782
|
});
|
|
780
783
|
} catch (a) {
|
|
781
784
|
throw console.error("下载失败:", a), a;
|
|
782
785
|
}
|
|
783
786
|
}
|
|
784
|
-
const
|
|
785
|
-
function
|
|
787
|
+
const F = () => `${Ae}/api/v4`, B = (e) => `${F()}/projects/100/repository/files/${encodeURIComponent(e)}/raw?ref=master`;
|
|
788
|
+
function Ps() {
|
|
786
789
|
return S({
|
|
787
|
-
url:
|
|
790
|
+
url: B("src/data/template-projects.json")
|
|
788
791
|
});
|
|
789
792
|
}
|
|
790
|
-
function
|
|
793
|
+
function Ds() {
|
|
791
794
|
return S({
|
|
792
|
-
url:
|
|
795
|
+
url: B("src/data/java-project-module.json")
|
|
793
796
|
});
|
|
794
797
|
}
|
|
795
|
-
function
|
|
798
|
+
function Os() {
|
|
796
799
|
return S({
|
|
797
|
-
url:
|
|
800
|
+
url: B("src/data/java-project-api.json")
|
|
798
801
|
});
|
|
799
802
|
}
|
|
800
803
|
function He() {
|
|
801
804
|
return S({
|
|
802
|
-
url:
|
|
805
|
+
url: B("src/data/z-develop-config.json")
|
|
803
806
|
});
|
|
804
807
|
}
|
|
805
|
-
function
|
|
808
|
+
function Ms() {
|
|
806
809
|
return S({
|
|
807
|
-
url:
|
|
810
|
+
url: B("src/assets/tsconfig.browser.json")
|
|
808
811
|
});
|
|
809
812
|
}
|
|
810
|
-
function
|
|
813
|
+
function Bs() {
|
|
811
814
|
return S({
|
|
812
|
-
url:
|
|
815
|
+
url: B("src/assets/tsconfig.node.json")
|
|
813
816
|
});
|
|
814
817
|
}
|
|
815
|
-
function
|
|
818
|
+
function zs() {
|
|
816
819
|
return S({
|
|
817
|
-
url:
|
|
820
|
+
url: B("src/assets/.prettierignore")
|
|
818
821
|
});
|
|
819
822
|
}
|
|
820
|
-
function
|
|
823
|
+
function _s() {
|
|
821
824
|
return S({
|
|
822
|
-
url:
|
|
825
|
+
url: B("src/assets/.prettierrc.json")
|
|
823
826
|
});
|
|
824
827
|
}
|
|
825
|
-
function
|
|
828
|
+
function Fs() {
|
|
826
829
|
return S({
|
|
827
|
-
url:
|
|
830
|
+
url: B("src/assets/data.yaml")
|
|
828
831
|
});
|
|
829
832
|
}
|
|
830
|
-
function
|
|
833
|
+
function Gs() {
|
|
831
834
|
return S({
|
|
832
|
-
url:
|
|
835
|
+
url: B("src/assets/main.py")
|
|
833
836
|
});
|
|
834
837
|
}
|
|
835
|
-
function
|
|
838
|
+
function Js() {
|
|
836
839
|
return S({
|
|
837
|
-
url:
|
|
840
|
+
url: B("src/assets/checkstyle.xml")
|
|
838
841
|
});
|
|
839
842
|
}
|
|
840
843
|
function Ct() {
|
|
841
844
|
return S({
|
|
842
|
-
url:
|
|
845
|
+
url: B("src/data/project-group-chats.json")
|
|
843
846
|
});
|
|
844
847
|
}
|
|
845
|
-
function
|
|
848
|
+
function Us() {
|
|
846
849
|
return S({
|
|
847
|
-
url:
|
|
850
|
+
url: B("src/data/project-zen-tao-id.json")
|
|
848
851
|
});
|
|
849
852
|
}
|
|
850
|
-
function
|
|
853
|
+
function Vs() {
|
|
851
854
|
return S({
|
|
852
|
-
url: `${
|
|
855
|
+
url: `${F()}/user`
|
|
853
856
|
});
|
|
854
857
|
}
|
|
855
|
-
function
|
|
858
|
+
function Ws() {
|
|
856
859
|
return S({
|
|
857
|
-
url: `${
|
|
860
|
+
url: `${F()}/groups`
|
|
858
861
|
});
|
|
859
862
|
}
|
|
860
|
-
function
|
|
863
|
+
function Hs(e) {
|
|
861
864
|
return S({
|
|
862
|
-
url: `${
|
|
865
|
+
url: `${F()}/projects`,
|
|
863
866
|
method: "post",
|
|
864
867
|
data: e
|
|
865
868
|
});
|
|
866
869
|
}
|
|
867
870
|
function Lt(e) {
|
|
868
871
|
return S({
|
|
869
|
-
url: `${
|
|
872
|
+
url: `${F()}/projects/${e}`
|
|
870
873
|
});
|
|
871
874
|
}
|
|
872
|
-
function
|
|
875
|
+
function qs(e) {
|
|
873
876
|
return S({
|
|
874
|
-
url: `${
|
|
877
|
+
url: `${F()}/projects`,
|
|
875
878
|
data: {
|
|
876
879
|
search: e,
|
|
877
880
|
search_namespaces: !0
|
|
878
881
|
}
|
|
879
882
|
});
|
|
880
883
|
}
|
|
881
|
-
function
|
|
884
|
+
function Zs(e) {
|
|
882
885
|
return S({
|
|
883
|
-
url: `${
|
|
886
|
+
url: `${F()}/projects/${e.id}/merge_requests`,
|
|
884
887
|
method: "post",
|
|
885
888
|
data: e
|
|
886
889
|
});
|
|
887
890
|
}
|
|
888
|
-
function
|
|
891
|
+
function Ks(e) {
|
|
889
892
|
return S({
|
|
890
|
-
url: `${
|
|
893
|
+
url: `${F()}/projects/${e.id}/merge_requests/${e.iid}/merge`,
|
|
891
894
|
method: "put"
|
|
892
895
|
});
|
|
893
896
|
}
|
|
894
|
-
function
|
|
897
|
+
function Ys(e) {
|
|
895
898
|
return S({
|
|
896
|
-
url: `${
|
|
899
|
+
url: `${F()}/projects/${e.id}/merge_requests/${e.iid}`,
|
|
897
900
|
method: "put",
|
|
898
901
|
data: e
|
|
899
902
|
});
|
|
900
903
|
}
|
|
901
|
-
function
|
|
904
|
+
function Xs(e) {
|
|
902
905
|
return S({
|
|
903
|
-
url: `${
|
|
906
|
+
url: `${F()}/projects/${e.id}/merge_requests/${e.iid}`,
|
|
904
907
|
method: "get"
|
|
905
908
|
});
|
|
906
909
|
}
|
|
907
|
-
function
|
|
910
|
+
function Qs(e) {
|
|
908
911
|
return S({
|
|
909
|
-
url: `${
|
|
912
|
+
url: `${F()}/projects/${e.id}/repository/branches`,
|
|
910
913
|
method: "post",
|
|
911
914
|
data: e
|
|
912
915
|
});
|
|
913
916
|
}
|
|
914
|
-
function
|
|
917
|
+
function en(e) {
|
|
915
918
|
return S({
|
|
916
|
-
url: `${
|
|
919
|
+
url: `${F()}/projects/${e}/repository/branches`
|
|
917
920
|
});
|
|
918
921
|
}
|
|
919
|
-
function
|
|
922
|
+
function tn() {
|
|
920
923
|
const e = Ne("fe-groups.json");
|
|
921
|
-
return j(e) ?
|
|
922
|
-
}
|
|
923
|
-
async function
|
|
924
|
-
const e = await
|
|
925
|
-
const
|
|
926
|
-
return
|
|
927
|
-
name:
|
|
928
|
-
id:
|
|
929
|
-
description:
|
|
924
|
+
return j(e) ? C.readJSONSync(e) : { groups: [] };
|
|
925
|
+
}
|
|
926
|
+
async function an() {
|
|
927
|
+
const e = await Ws(), t = Ia.map((a) => {
|
|
928
|
+
const n = e.find((s) => s.name === a);
|
|
929
|
+
return n ? {
|
|
930
|
+
name: n.name,
|
|
931
|
+
id: n.id,
|
|
932
|
+
description: n.description
|
|
930
933
|
} : !1;
|
|
931
934
|
}).filter((a) => !!a);
|
|
932
|
-
|
|
935
|
+
C.writeJSONSync(Ne("fe-groups.json"), { groups: t }, { spaces: 2 });
|
|
933
936
|
}
|
|
934
|
-
function
|
|
937
|
+
function sn(e, t) {
|
|
935
938
|
const a = [];
|
|
936
939
|
t.forEach((i) => {
|
|
937
940
|
e.includes(i.value) && a.push(i);
|
|
938
941
|
});
|
|
939
|
-
const
|
|
942
|
+
const n = be("weWorkListCache"), s = n.map((i) => i.value);
|
|
940
943
|
a.forEach((i) => {
|
|
941
|
-
const o =
|
|
942
|
-
o > -1 ?
|
|
944
|
+
const o = s.indexOf(i.value);
|
|
945
|
+
o > -1 ? n[o].usageCount += 1 : n.push({
|
|
943
946
|
...i,
|
|
944
947
|
usageCount: 1
|
|
945
948
|
});
|
|
946
949
|
}), de({
|
|
947
|
-
weWorkListCache:
|
|
950
|
+
weWorkListCache: n.sort((i, o) => o.usageCount - i.usageCount)
|
|
948
951
|
}), X();
|
|
949
952
|
}
|
|
950
953
|
async function xt() {
|
|
951
|
-
const t = (await
|
|
954
|
+
const t = (await is()).filter((i) => [1, 2, 3, 4, 5].includes(i.title)).map((i) => ({
|
|
952
955
|
name: `${i.nick} - ${Ea[i.title]}`,
|
|
953
956
|
value: i.weWorkUserId
|
|
954
|
-
})), a = be("weWorkListCache"),
|
|
957
|
+
})), a = be("weWorkListCache"), n = a.map((i) => i.value), s = [];
|
|
955
958
|
return t.forEach((i) => {
|
|
956
|
-
const o =
|
|
957
|
-
|
|
959
|
+
const o = n.indexOf(i.value);
|
|
960
|
+
s.push({
|
|
958
961
|
...i,
|
|
959
962
|
usageCount: o > -1 ? a[o].usageCount : 0
|
|
960
963
|
});
|
|
961
|
-
}),
|
|
964
|
+
}), s.sort((i, o) => o.usageCount - i.usageCount);
|
|
962
965
|
}
|
|
963
966
|
async function Pt(e, t, a) {
|
|
964
|
-
const
|
|
965
|
-
let
|
|
967
|
+
const n = await xt();
|
|
968
|
+
let s = await V({
|
|
966
969
|
message: e,
|
|
967
970
|
loop: !0,
|
|
968
|
-
pageSize:
|
|
971
|
+
pageSize: n.length || 5,
|
|
969
972
|
clearInputWhenSelected: !0,
|
|
970
973
|
multiple: a,
|
|
971
|
-
options: (i) => i ?
|
|
974
|
+
options: (i) => i ? n.filter((o) => o.name.includes(i)) : n,
|
|
972
975
|
validate: t
|
|
973
976
|
});
|
|
974
|
-
return
|
|
977
|
+
return s = Array.isArray(s) ? s : [s], sn(s, n), s;
|
|
975
978
|
}
|
|
976
|
-
async function
|
|
977
|
-
const { groups:
|
|
979
|
+
async function nn(e, t, a) {
|
|
980
|
+
const { groups: n } = await Ct(), s = n.map((o) => ({
|
|
978
981
|
name: o.name,
|
|
979
982
|
value: o.url
|
|
980
983
|
}));
|
|
981
984
|
let i = await V({
|
|
982
985
|
message: e,
|
|
983
986
|
loop: !0,
|
|
984
|
-
pageSize:
|
|
987
|
+
pageSize: s.length || 5,
|
|
985
988
|
clearInputWhenSelected: !0,
|
|
986
989
|
multiple: a,
|
|
987
|
-
options: (o) => o ?
|
|
990
|
+
options: (o) => o ? s.filter((r) => r.name.includes(o)) : s,
|
|
988
991
|
validate: t
|
|
989
992
|
});
|
|
990
993
|
return i = Array.isArray(i) ? i : [i], i;
|
|
991
994
|
}
|
|
992
|
-
async function
|
|
995
|
+
async function rn() {
|
|
993
996
|
try {
|
|
994
997
|
jt() && (await Le({
|
|
995
998
|
message: "系统中已存在z的配置文件,确认重新配置?"
|
|
@@ -1011,17 +1014,17 @@ async function rs() {
|
|
|
1011
1014
|
}
|
|
1012
1015
|
]
|
|
1013
1016
|
});
|
|
1014
|
-
let a = await
|
|
1017
|
+
let a = await _({
|
|
1015
1018
|
message: "请输入LDAP账号:"
|
|
1016
1019
|
});
|
|
1017
1020
|
a = a.trim();
|
|
1018
|
-
let
|
|
1021
|
+
let n = await pa({
|
|
1019
1022
|
message: "请输入LDAP密码:",
|
|
1020
1023
|
mask: !0
|
|
1021
1024
|
});
|
|
1022
|
-
|
|
1023
|
-
const
|
|
1024
|
-
De(
|
|
1025
|
+
n = n.trim(), k("jobType", t), k("ldapAccount", a), k("ldapPassword", n);
|
|
1026
|
+
const s = await He();
|
|
1027
|
+
De(s);
|
|
1025
1028
|
const i = await xt(), o = await Pt("请选择你自己(用于企微通知):", (u) => u.length > 1 ? "只能选一个" : u.length < 1 ? "请选一个" : !0), { name: r, value: c } = i.find((u) => u.value === o[0]);
|
|
1026
1029
|
k({
|
|
1027
1030
|
weWorkName: r,
|
|
@@ -1032,55 +1035,55 @@ async function rs() {
|
|
|
1032
1035
|
}
|
|
1033
1036
|
const e = y("配置信息初始化中").start();
|
|
1034
1037
|
try {
|
|
1035
|
-
const t = await
|
|
1038
|
+
const t = await Vs();
|
|
1036
1039
|
k({
|
|
1037
1040
|
gitUserId: t.id,
|
|
1038
1041
|
gitName: t.name,
|
|
1039
1042
|
gitEnglishName: t.username,
|
|
1040
1043
|
gitEmail: t.email
|
|
1041
|
-
}), de("latestCheckVersionTimestamp", Date.now()), X(), I("jobType") === ue.FRONT_END && await
|
|
1044
|
+
}), de("latestCheckVersionTimestamp", Date.now()), X(), I("jobType") === ue.FRONT_END && await an(), e.succeed("配置信息初始化完成"), process.exit(0);
|
|
1042
1045
|
} catch (t) {
|
|
1043
1046
|
e.fail("配置信息初始化失败"), me.isAxiosError(t) && m("请检查你的域名及令牌配置"), m(t);
|
|
1044
1047
|
}
|
|
1045
1048
|
}
|
|
1046
1049
|
const ke = (e, t, a) => {
|
|
1047
|
-
const
|
|
1050
|
+
const n = [
|
|
1048
1051
|
"#!/usr/bin/env sh",
|
|
1049
1052
|
...Array.isArray(t) ? t : [t],
|
|
1050
1053
|
""
|
|
1051
1054
|
].join(`
|
|
1052
1055
|
`).trim();
|
|
1053
|
-
ve(
|
|
1056
|
+
ve(L(e), n, {
|
|
1054
1057
|
mode: 493
|
|
1055
1058
|
});
|
|
1056
|
-
},
|
|
1059
|
+
}, on = () => {
|
|
1057
1060
|
ke("commit-msg", "z run commit-msg"), ke("pre-commit", "z run commit-files"), ke("pre-rebase", "z run not-allow-rebase"), ke("pre-push", "z run detect-push");
|
|
1058
1061
|
};
|
|
1059
|
-
async function
|
|
1060
|
-
await
|
|
1061
|
-
`, { mode: 493 }),
|
|
1062
|
+
async function cn() {
|
|
1063
|
+
await z(Se(), "", { mode: 493 }), await z(L(".gitignore"), `.commit-msg-tpl
|
|
1064
|
+
`, { mode: 493 }), on();
|
|
1062
1065
|
const { language: e } = W();
|
|
1063
|
-
if ([$.JAVASCRIPT, $.MARKDOWN].includes(e) && (await
|
|
1064
|
-
|
|
1065
|
-
`${JSON.stringify(await
|
|
1066
|
+
if ([$.JAVASCRIPT, $.MARKDOWN].includes(e) && (await z(
|
|
1067
|
+
L(".prettierrc.json"),
|
|
1068
|
+
`${JSON.stringify(await _s(), null, 2)}
|
|
1066
1069
|
`,
|
|
1067
1070
|
{
|
|
1068
1071
|
mode: 493
|
|
1069
1072
|
}
|
|
1070
|
-
), await
|
|
1071
|
-
await
|
|
1073
|
+
), await z(L(".prettierignore"), await zs(), { mode: 493 }), await z(L("tsconfig.node.json"), await Bs(), { mode: 493 }), await z(L("tsconfig.browser.json"), await Ms(), { mode: 493 })), e === $.JAVA) {
|
|
1074
|
+
await xs(`${re("FECDNDomain")}/file/vgnlfbfHRF.jar`, L("checkstyle.jar")), await z(L("checkstyle.xml"), await Js(), { mode: 493 });
|
|
1072
1075
|
const t = f.join("package.json");
|
|
1073
|
-
j(t) || await
|
|
1076
|
+
j(t) || await z(t, JSON.stringify({ version: "0.0.1" }, null, 2), {
|
|
1074
1077
|
mode: 493
|
|
1075
1078
|
});
|
|
1076
1079
|
}
|
|
1077
1080
|
Nt(), await p(`git add ${K}`);
|
|
1078
1081
|
}
|
|
1079
|
-
async function
|
|
1082
|
+
async function ln(e, t) {
|
|
1080
1083
|
const a = await p("git remote get-url --push origin");
|
|
1081
1084
|
a || m("获取项目远程git地址失败,请配置后重试");
|
|
1082
|
-
let
|
|
1083
|
-
|
|
1085
|
+
let n = e;
|
|
1086
|
+
n || (n = await E({
|
|
1084
1087
|
message: "请选择项目语言",
|
|
1085
1088
|
choices: [
|
|
1086
1089
|
{
|
|
@@ -1101,65 +1104,65 @@ async function ls(e, t) {
|
|
|
1101
1104
|
}
|
|
1102
1105
|
]
|
|
1103
1106
|
}));
|
|
1104
|
-
let
|
|
1105
|
-
if (!
|
|
1106
|
-
const o =
|
|
1107
|
+
let s = t;
|
|
1108
|
+
if (!s) {
|
|
1109
|
+
const o = se(a), r = await Lt(o);
|
|
1107
1110
|
if (!r)
|
|
1108
1111
|
return m(`未找到项目,请确认项目${a}是否存在,或者当前账号权限`);
|
|
1109
|
-
|
|
1112
|
+
s = r.namespace.full_path;
|
|
1110
1113
|
}
|
|
1111
1114
|
let i = await Le({
|
|
1112
1115
|
message: "是否允许直接推送代码到环境分支?默认否",
|
|
1113
1116
|
default: !1
|
|
1114
1117
|
});
|
|
1115
1118
|
if (i) {
|
|
1116
|
-
const o = await
|
|
1119
|
+
const o = await _({
|
|
1117
1120
|
message: `⚠️警告:请再次确认本项目允许直接推送代码到环境分支!!这意味着本项目可以在环境分支上进行开发,这一般用于与部署环境无关、或者单一部署环境的项目。
|
|
1118
1121
|
请输入【是/yes/y/Y】以确认;输入其他或者不输入则表示不允许直接推送:`
|
|
1119
1122
|
});
|
|
1120
1123
|
i = ["是", "yes", "y", "Y"].includes(o), i || J("✅ 已修改为不允许直接推送代码到分支环境");
|
|
1121
1124
|
}
|
|
1122
1125
|
It({
|
|
1123
|
-
language:
|
|
1124
|
-
"lint-staged": Va[
|
|
1126
|
+
language: n,
|
|
1127
|
+
"lint-staged": Va[n],
|
|
1125
1128
|
repository: {
|
|
1126
1129
|
url: a,
|
|
1127
|
-
group:
|
|
1130
|
+
group: s
|
|
1128
1131
|
},
|
|
1129
1132
|
skipGitPushLimit: i
|
|
1130
1133
|
});
|
|
1131
1134
|
}
|
|
1132
1135
|
async function qe(e, t) {
|
|
1133
|
-
e ? N.rm("-rf", K) : j(
|
|
1136
|
+
e ? N.rm("-rf", K) : j(L()) && (await Le({
|
|
1134
1137
|
message: `当前项目中已存在配置文件夹${K},确认重新配置?`
|
|
1135
|
-
}) ? N.rm("-rf", K) : process.exit(0)), await fe(
|
|
1138
|
+
}) ? N.rm("-rf", K) : process.exit(0)), await fe(L(), { recursive: !0 }), await ln(e, t);
|
|
1136
1139
|
const a = y("项目初始化中...").start();
|
|
1137
|
-
await
|
|
1140
|
+
await cn(), a.succeed("项目初始化完成");
|
|
1138
1141
|
}
|
|
1139
|
-
async function
|
|
1140
|
-
j(
|
|
1142
|
+
async function un() {
|
|
1143
|
+
j(L()) && j(Se()) ? Nt() : await qe(), process.exit(0);
|
|
1141
1144
|
}
|
|
1142
|
-
async function
|
|
1143
|
-
t.projectLanguage && !Object.values($).includes(t.projectLanguage) && m("项目语言不支持"), e ? (H(), e === "." ? (await qe(t.projectLanguage, void 0), process.exit(0)) : e === "prepare" ? await
|
|
1145
|
+
async function pn(e, t) {
|
|
1146
|
+
t.projectLanguage && !Object.values($).includes(t.projectLanguage) && m("项目语言不支持"), e ? (H(), e === "." ? (await qe(t.projectLanguage, void 0), process.exit(0)) : e === "prepare" ? await un() : m("参数错误。执行 z init -h 查看帮助。")) : await rn();
|
|
1144
1147
|
}
|
|
1145
|
-
|
|
1146
|
-
async function
|
|
1148
|
+
x.command("init").alias("i").description("初始化工具配置、项目配置").argument("[type]", "非必填。不传为初始化全局配置;传 . 为初始化当前项目;传 prepare 为初始化GIT HOOKS").option("--project-language", `项目语言。可选值:${Object.values($).join("/")} `).action((...e) => M(pn, ...e));
|
|
1149
|
+
async function mn(e, t) {
|
|
1147
1150
|
if (!e)
|
|
1148
1151
|
return "不能为空";
|
|
1149
1152
|
if (!/^[a-z0-9-]+$/.test(e))
|
|
1150
1153
|
return "格式为小写字母、中横线(可选)、数字(不推荐)。如apple, apple-tree";
|
|
1151
1154
|
if (kt().includes(e))
|
|
1152
1155
|
return "当前目录下已存在同名文件夹,请先处理。";
|
|
1153
|
-
const
|
|
1154
|
-
return
|
|
1156
|
+
const s = (await qs(e)).find((i) => i.path_with_namespace === `${t}/${e}`);
|
|
1157
|
+
return s ? `远程仓库中已存在同名项目(${s.http_url_to_repo}),请更名后重试` : !0;
|
|
1155
1158
|
}
|
|
1156
|
-
function
|
|
1159
|
+
function dn(e) {
|
|
1157
1160
|
return e ? !0 : "不能为空";
|
|
1158
1161
|
}
|
|
1159
|
-
function
|
|
1162
|
+
function fn(e) {
|
|
1160
1163
|
return e ? /^[a-zA-Z0-9.]+$/.test(e) ? !0 : "格式为大小写字母、数字、小数点,小驼峰命名。如userInfo、systemRouter3" : "不能为空";
|
|
1161
1164
|
}
|
|
1162
|
-
async function
|
|
1165
|
+
async function gn(e) {
|
|
1163
1166
|
ee(), H(), await ge();
|
|
1164
1167
|
let t, a;
|
|
1165
1168
|
e.branchType ? t = e.branchType : t = await E({
|
|
@@ -1178,15 +1181,15 @@ async function gs(e) {
|
|
|
1178
1181
|
value: $e.REFACTOR
|
|
1179
1182
|
}
|
|
1180
1183
|
]
|
|
1181
|
-
}), e.branchPurpose ? a = e.branchPurpose : (a = await
|
|
1184
|
+
}), e.branchPurpose ? a = e.branchPurpose : (a = await _({
|
|
1182
1185
|
message: "请输入创建分支的目的(大小写字母、数字,小驼峰式命名。如userInfo)",
|
|
1183
|
-
validate:
|
|
1186
|
+
validate: fn
|
|
1184
1187
|
}), a = a.trim());
|
|
1185
|
-
const
|
|
1186
|
-
await p(`git fetch origin ${w.MASTER}`), await p(`git checkout -b ${
|
|
1188
|
+
const n = `${t}_${a}_${Et()}`;
|
|
1189
|
+
await p(`git fetch origin ${w.MASTER}`), await p(`git checkout -b ${n} origin/${w.MASTER}`), await p(`git push -u origin ${n}`), process.exit(0);
|
|
1187
1190
|
}
|
|
1188
1191
|
const Dt = (e) => `${re("ZenTaoDomain")}${e}`;
|
|
1189
|
-
async function
|
|
1192
|
+
async function hn() {
|
|
1190
1193
|
const e = await Ce({
|
|
1191
1194
|
url: Dt("/my-work-task.json?tid=mrrferp8"),
|
|
1192
1195
|
method: "get"
|
|
@@ -1199,7 +1202,7 @@ async function hs() {
|
|
|
1199
1202
|
name: a
|
|
1200
1203
|
})) : [];
|
|
1201
1204
|
}
|
|
1202
|
-
async function
|
|
1205
|
+
async function wn() {
|
|
1203
1206
|
const e = await Ce({
|
|
1204
1207
|
url: Dt("/my-work-bug.json?tid=mrrferp8"),
|
|
1205
1208
|
method: "get"
|
|
@@ -1212,7 +1215,7 @@ async function ws() {
|
|
|
1212
1215
|
}
|
|
1213
1216
|
})) : [];
|
|
1214
1217
|
}
|
|
1215
|
-
const Ge = async () => (await
|
|
1218
|
+
const Ge = async () => (await _({
|
|
1216
1219
|
message: "请输入commit msg:",
|
|
1217
1220
|
validate: (t) => t.length === 0 ? "请输入commit msg" : !0
|
|
1218
1221
|
})).trim();
|
|
@@ -1220,7 +1223,7 @@ async function ct(e, t) {
|
|
|
1220
1223
|
const a = await p("git diff HEAD", {
|
|
1221
1224
|
removeTailLinkBreak: !1
|
|
1222
1225
|
});
|
|
1223
|
-
if (a || m("git暂存区没有内容,请先git add添加文件到暂存区"), Buffer.byteLength(a, "utf-8") <
|
|
1226
|
+
if (a || m("git暂存区没有内容,请先git add添加文件到暂存区"), Buffer.byteLength(a, "utf-8") < st) {
|
|
1224
1227
|
const u = await rt({
|
|
1225
1228
|
type: "commit-message-v2",
|
|
1226
1229
|
input: a
|
|
@@ -1228,12 +1231,12 @@ async function ct(e, t) {
|
|
|
1228
1231
|
});
|
|
1229
1232
|
return e + u;
|
|
1230
1233
|
}
|
|
1231
|
-
const
|
|
1232
|
-
|
|
1233
|
-
const
|
|
1234
|
+
const n = await p("git diff --name-only HEAD");
|
|
1235
|
+
n || m("git暂存区没有内容,请先git add添加文件到暂存区");
|
|
1236
|
+
const s = n.replace(/\r\n/g, `
|
|
1234
1237
|
`).split(`
|
|
1235
1238
|
`).filter(Boolean), i = [], o = [];
|
|
1236
|
-
for (const u of
|
|
1239
|
+
for (const u of s)
|
|
1237
1240
|
try {
|
|
1238
1241
|
const l = u.replace(/(["\\$`])/g, "\\$1"), d = await p(`git diff HEAD -- "${l}"`, {
|
|
1239
1242
|
removeTailLinkBreak: !1
|
|
@@ -1243,7 +1246,7 @@ async function ct(e, t) {
|
|
|
1243
1246
|
}
|
|
1244
1247
|
const r = o.join(`
|
|
1245
1248
|
`);
|
|
1246
|
-
if (i.length === 0 || Buffer.byteLength(r, "utf-8") >
|
|
1249
|
+
if (i.length === 0 || Buffer.byteLength(r, "utf-8") > st)
|
|
1247
1250
|
return J("变更内容太大,无法自动生成commit msg"), t.stop(), await Ge();
|
|
1248
1251
|
if (!r)
|
|
1249
1252
|
return J("无法获取文件差异信息"), t.stop(), await Ge();
|
|
@@ -1255,18 +1258,18 @@ async function ct(e, t) {
|
|
|
1255
1258
|
return e + c;
|
|
1256
1259
|
}
|
|
1257
1260
|
async function ze(e, t, a) {
|
|
1258
|
-
const
|
|
1259
|
-
let
|
|
1261
|
+
const n = y("🤖 生成提交信息中...").start();
|
|
1262
|
+
let s = "", i = !0;
|
|
1260
1263
|
if ([T.FEAT, T.FIX, T.REFACTOR].includes(e)) {
|
|
1261
1264
|
const o = t.map((r) => r.value).join(",");
|
|
1262
|
-
if (a || (
|
|
1265
|
+
if (a || (s = await ct(`${e}(${o}): `, n)), !s) {
|
|
1263
1266
|
const r = t.map((c) => c.name).join(";");
|
|
1264
|
-
|
|
1267
|
+
s = `${e}(${o}): ${r}`, i = !1;
|
|
1265
1268
|
}
|
|
1266
1269
|
}
|
|
1267
|
-
e === T.CHORE && (t ?
|
|
1270
|
+
e === T.CHORE && (t ? s = `${e}: ${t}` : s = await ct(`${e}: `, n)), await z(Se(), s, "utf-8"), i || a ? n.succeed("提交信息已生成(↓),可以进行提交了!") : n.warn("AI生成提交信息失败,已使用默认模板(↓),可以进行提交了!"), console.log(A.yellow(s));
|
|
1268
1271
|
}
|
|
1269
|
-
async function
|
|
1272
|
+
async function yn({ commitMessageCloseAi: e, commitMessageUseChoreType: t }) {
|
|
1270
1273
|
let a;
|
|
1271
1274
|
if (t ? a = T.CHORE : a = await E({
|
|
1272
1275
|
message: "请选择你要创建的模板类型",
|
|
@@ -1289,60 +1292,60 @@ async function ys({ commitMessageCloseAi: e, commitMessageUseChoreType: t }) {
|
|
|
1289
1292
|
}
|
|
1290
1293
|
]
|
|
1291
1294
|
}), [T.FEAT, T.REFACTOR].includes(a)) {
|
|
1292
|
-
const
|
|
1293
|
-
if (!
|
|
1295
|
+
const n = await hn();
|
|
1296
|
+
if (!n.length)
|
|
1294
1297
|
return U("🤷 暂无开发任务");
|
|
1295
|
-
const
|
|
1298
|
+
const s = await Re({
|
|
1296
1299
|
message: "请关联开发任务(可多选):",
|
|
1297
1300
|
validate: (i) => i.length === 0 ? "请选择项" : !0,
|
|
1298
|
-
choices:
|
|
1301
|
+
choices: n.map((i) => ({
|
|
1299
1302
|
...i,
|
|
1300
1303
|
name: `[${i.value.value}]: ${i.name}`
|
|
1301
1304
|
})),
|
|
1302
|
-
pageSize:
|
|
1305
|
+
pageSize: n.length
|
|
1303
1306
|
});
|
|
1304
|
-
await ze(T.FEAT,
|
|
1307
|
+
await ze(T.FEAT, s, e);
|
|
1305
1308
|
}
|
|
1306
1309
|
if (a === T.FIX) {
|
|
1307
|
-
const
|
|
1308
|
-
if (!
|
|
1310
|
+
const n = await wn();
|
|
1311
|
+
if (!n.length)
|
|
1309
1312
|
return U("🤷 暂无BUG");
|
|
1310
|
-
const
|
|
1313
|
+
const s = await Re({
|
|
1311
1314
|
message: "请关联Bug(可多选):",
|
|
1312
1315
|
validate: (i) => i.length === 0 ? "请选择项" : !0,
|
|
1313
|
-
choices:
|
|
1316
|
+
choices: n.map((i) => ({
|
|
1314
1317
|
...i,
|
|
1315
1318
|
name: `[${i.value.value}]: ${i.name}`
|
|
1316
1319
|
})),
|
|
1317
|
-
pageSize:
|
|
1320
|
+
pageSize: n.length
|
|
1318
1321
|
});
|
|
1319
|
-
await ze(T.FIX,
|
|
1322
|
+
await ze(T.FIX, s, e);
|
|
1320
1323
|
}
|
|
1321
1324
|
if (a === T.CHORE) {
|
|
1322
|
-
let
|
|
1323
|
-
e && (
|
|
1325
|
+
let n = "";
|
|
1326
|
+
e && (n = await Ge()), await ze(T.CHORE, n);
|
|
1324
1327
|
}
|
|
1325
1328
|
process.exit(0);
|
|
1326
1329
|
}
|
|
1327
|
-
async function $
|
|
1330
|
+
async function $n() {
|
|
1328
1331
|
try {
|
|
1329
1332
|
const e = {}, t = async () => {
|
|
1330
|
-
const
|
|
1333
|
+
const P = kt(), { projects: oe } = await Ps(), te = oe.map((le) => {
|
|
1331
1334
|
const et = {
|
|
1332
1335
|
name: `${le.name} [${le.desc}]`,
|
|
1333
1336
|
value: le.name,
|
|
1334
1337
|
disabled: !1
|
|
1335
1338
|
};
|
|
1336
|
-
return
|
|
1339
|
+
return P.includes(le.name) && (et.disabled = "目录下已存在同名文件夹"), et;
|
|
1337
1340
|
}), Kt = await E({
|
|
1338
1341
|
message: "请选择一个项目模板",
|
|
1339
1342
|
choices: te
|
|
1340
1343
|
}), Be = oe.find((le) => le.name === Kt);
|
|
1341
1344
|
e.tplName = Be.name, e.tplUrl = Be.url, e.tplLanguage = Be.language;
|
|
1342
1345
|
}, a = async () => {
|
|
1343
|
-
const { groups:
|
|
1346
|
+
const { groups: P } = tn(), oe = await E({
|
|
1344
1347
|
message: "请选择一个分组",
|
|
1345
|
-
choices:
|
|
1348
|
+
choices: P.map((te) => ({
|
|
1346
1349
|
name: `${te.name} [${te.description}]`,
|
|
1347
1350
|
value: te.id,
|
|
1348
1351
|
short: te.name
|
|
@@ -1350,22 +1353,22 @@ async function $s() {
|
|
|
1350
1353
|
});
|
|
1351
1354
|
e.group = {
|
|
1352
1355
|
id: oe,
|
|
1353
|
-
name:
|
|
1356
|
+
name: P.find((te) => te.id === oe)?.name
|
|
1354
1357
|
};
|
|
1355
|
-
},
|
|
1356
|
-
e.projectName = await
|
|
1358
|
+
}, n = async () => {
|
|
1359
|
+
e.projectName = await _({
|
|
1357
1360
|
message: "请输入项目名称",
|
|
1358
|
-
validate: (
|
|
1359
|
-
}), e.projectName = e.projectName.trim(), e.projectDesc = await
|
|
1361
|
+
validate: (P) => mn(P, e.group?.name || "")
|
|
1362
|
+
}), e.projectName = e.projectName.trim(), e.projectDesc = await _({
|
|
1360
1363
|
message: "请输入项目描述",
|
|
1361
|
-
validate:
|
|
1364
|
+
validate: dn
|
|
1362
1365
|
}), e.projectDesc = e.projectDesc.trim();
|
|
1363
1366
|
};
|
|
1364
|
-
await t(), await a(), await
|
|
1365
|
-
const
|
|
1366
|
-
await p(`git clone --depth=1 ${e.tplUrl}`), await ft(e.tplName, e.projectName), N.cd(e.projectName), N.rm("-rf", ".git"), await p(`git init --initial-branch=${w.MASTER}`), await p(`git remote add origin ${
|
|
1367
|
+
await t(), await a(), await n();
|
|
1368
|
+
const s = `${Ae}/${e.group?.name}/${e.projectName}.git`, i = y("模版初始化中").start();
|
|
1369
|
+
await p(`git clone --depth=1 ${e.tplUrl}`), await ft(e.tplName, e.projectName), N.cd(e.projectName), N.rm("-rf", ".git"), await p(`git init --initial-branch=${w.MASTER}`), await p(`git remote add origin ${s}`), await p(`git config user.name ${I("gitName")}`), await p(`git config user.email ${I("gitEmail")}`);
|
|
1367
1370
|
const o = We();
|
|
1368
|
-
|
|
1371
|
+
as({
|
|
1369
1372
|
...o,
|
|
1370
1373
|
name: e.projectName,
|
|
1371
1374
|
description: e.projectDesc,
|
|
@@ -1373,38 +1376,38 @@ async function $s() {
|
|
|
1373
1376
|
...o.scripts,
|
|
1374
1377
|
prepare: "[ -n '$z' ] && z init prepare || echo 'Warning: z not exist at global'"
|
|
1375
1378
|
}
|
|
1376
|
-
}), await
|
|
1379
|
+
}), await C.writeFile(f.resolve("README.md"), Ua(e.projectName, e.projectDesc)), i.succeed("模版初始化完成"), await qe(e.tplLanguage, e.group?.name);
|
|
1377
1380
|
const r = y("依赖安装中").start();
|
|
1378
1381
|
await p("npm install --registry https://registry.npmmirror.com/"), r.succeed("依赖安装完成");
|
|
1379
1382
|
const c = y("项目推送中").start();
|
|
1380
1383
|
await p('git add . && git commit -m "chore: 项目初始化"'), await p("git tag v0.0.1");
|
|
1381
|
-
const u = await
|
|
1384
|
+
const u = await Hs({
|
|
1382
1385
|
name: e.projectName,
|
|
1383
1386
|
description: e.projectDesc,
|
|
1384
1387
|
path: e.projectName,
|
|
1385
1388
|
visibility: "private",
|
|
1386
1389
|
namespace_id: e.group?.id
|
|
1387
1390
|
});
|
|
1388
|
-
await p(`git push -u origin ${w.MASTER} --no-verify`), await p(`git push origin HEAD:${w.MASTER} --tags --no-verify`), c.succeed(`项目已推送到远程,地址: ${A.blue(
|
|
1391
|
+
await p(`git push -u origin ${w.MASTER} --no-verify`), await p(`git push origin HEAD:${w.MASTER} --tags --no-verify`), c.succeed(`项目已推送到远程,地址: ${A.blue(s)}`);
|
|
1389
1392
|
const l = y("初始化分支中").start(), d = `feat_init_${Et()}`, g = [w.DEV, w.TEST, w.RELEASE, d], h = await Promise.allSettled(
|
|
1390
1393
|
g.map(
|
|
1391
|
-
(
|
|
1394
|
+
(P) => Qs({
|
|
1392
1395
|
id: u.id,
|
|
1393
|
-
branch:
|
|
1396
|
+
branch: P,
|
|
1394
1397
|
ref: w.MASTER
|
|
1395
1398
|
})
|
|
1396
1399
|
)
|
|
1397
1400
|
), v = [];
|
|
1398
|
-
h.forEach(({ status:
|
|
1399
|
-
|
|
1401
|
+
h.forEach(({ status: P }, oe) => {
|
|
1402
|
+
P === "fulfilled" && v.push(g[oe]);
|
|
1400
1403
|
}), await p("git pull"), v.includes(d) ? (await p(`git checkout -b ${d} origin/${d}`), l.succeed(`项目已切换到初始分支: ${A.blue(d)}`)) : l.warn("开发分支检出失败!项目当前在主分支,请自行检出开发分支。");
|
|
1401
|
-
const
|
|
1402
|
-
console.log(`输入 ${A.green(
|
|
1404
|
+
const G = `cd ${e.projectName}`;
|
|
1405
|
+
console.log(`输入 ${A.green(G)} 开始开发吧~`), process.exit(0);
|
|
1403
1406
|
} catch (e) {
|
|
1404
1407
|
m(e);
|
|
1405
1408
|
}
|
|
1406
1409
|
}
|
|
1407
|
-
async function
|
|
1410
|
+
async function vn(e, t) {
|
|
1408
1411
|
let a;
|
|
1409
1412
|
e ? [
|
|
1410
1413
|
"project",
|
|
@@ -1437,16 +1440,16 @@ async function vs(e, t) {
|
|
|
1437
1440
|
/* Project */
|
|
1438
1441
|
}
|
|
1439
1442
|
]
|
|
1440
|
-
}), a === "project" ? await $
|
|
1443
|
+
}), a === "project" ? await $n() : (ee(), H(), a === "branch" ? await gn(t) : a === "commit-msg" && (await p("git status -s") ? await yn(t) : m("没有要变动的文件,无法生成提交信息")));
|
|
1441
1444
|
}
|
|
1442
|
-
|
|
1443
|
-
const
|
|
1444
|
-
const t = await
|
|
1445
|
+
x.command("create").alias("c").description("创建项目/分支/提交信息").argument("[type]", "可选值为project|pr, branch|b, commit-msg|cm").option("--branch-type <type>", `分支类型。可选值:${Object.values($e).join(", ")}`).option("--branch-purpose <purpose>", "创建分支的目的").option("--commit-message-close-ai", "创建提交信息时,是否关闭AI生成").option("-c, --commit-message-use-chore-type", "创建提交信息时,直接使用chore类型。").action((...e) => M(vn, ...e));
|
|
1446
|
+
const An = async (e) => {
|
|
1447
|
+
const t = await Ls(), a = I("weWorkUserId"), { notifyUsers: n, notifyGroups: s, ...i } = e, o = y("部署任务创建中").start(), r = await Ns({
|
|
1445
1448
|
...i,
|
|
1446
1449
|
userToken: t,
|
|
1447
1450
|
userWeworkId: a,
|
|
1448
|
-
notifyUsers: [.../* @__PURE__ */ new Set([a, ...
|
|
1449
|
-
notifyGroups:
|
|
1451
|
+
notifyUsers: [.../* @__PURE__ */ new Set([a, ...n])].join(Fe),
|
|
1452
|
+
notifyGroups: s.join(Fe)
|
|
1450
1453
|
});
|
|
1451
1454
|
i.moduleNames.length > 1 ? (o.succeed(`多模块部署任务创建完成,共 ${i.moduleNames.length} 个模块`), o.succeed(`当前已创建首个模块 ${A.blue(i.moduleNames[0])} 的 k8s 地址:`), console.log(A.blue(r)), o.info("后续模块会在前一个模块完成后依次部署,并通过企微通知下发对应地址。")) : (o.succeed("部署任务创建完成"), console.log(`如有需要,可在k8s中查看 ${A.blue(r)}`));
|
|
1452
1455
|
}, Ze = () => {
|
|
@@ -1456,124 +1459,128 @@ const As = async (e) => {
|
|
|
1456
1459
|
const e = W();
|
|
1457
1460
|
return e.repository?.url || m("未找到当前项目的仓库地址,请先通过 z . 对项目进行初始化"), e.repository.url;
|
|
1458
1461
|
}, Mt = async () => {
|
|
1459
|
-
const e = Ot(), t = Ze(), { groups: a } = await
|
|
1460
|
-
return a.find((
|
|
1461
|
-
const
|
|
1462
|
-
return
|
|
1462
|
+
const e = Ot(), t = Ze(), { groups: a } = await Us();
|
|
1463
|
+
return a.find((n) => {
|
|
1464
|
+
const s = $.JAVASCRIPT === t ? n.projects?.web : $.JAVA === t ? n.projects?.server : [];
|
|
1465
|
+
return s.length && s.some((i) => Pe(i.url, e)) && n.zenTaoProductId ? n.zenTaoProductId : !1;
|
|
1463
1466
|
});
|
|
1464
|
-
},
|
|
1467
|
+
}, bn = async () => {
|
|
1465
1468
|
const e = await Mt();
|
|
1466
1469
|
if (!e)
|
|
1467
1470
|
return;
|
|
1468
|
-
const t = Ot(), a = Ze(),
|
|
1469
|
-
return
|
|
1471
|
+
const t = Ot(), a = Ze(), n = $.JAVASCRIPT === a ? e.projects?.web : $.JAVA === a ? e.projects?.server : [];
|
|
1472
|
+
return n.length ? n.find((i) => Pe(i.url, t))?.chatGroupWebhook ?? e.chatGroupWebhook : void 0;
|
|
1470
1473
|
};
|
|
1471
|
-
function
|
|
1474
|
+
function Sn(e, t) {
|
|
1472
1475
|
const a = We();
|
|
1473
1476
|
if (W()?.repository?.url || m(".z/project.json中缺少repository.url"), t === Y.H5) {
|
|
1474
|
-
const
|
|
1475
|
-
a?.scripts[
|
|
1477
|
+
const s = `build:${e}`;
|
|
1478
|
+
a?.scripts[s] || m(`项目package.json文件scripts不存在命令${s}。`);
|
|
1476
1479
|
}
|
|
1477
1480
|
t === Y.NPM && (a?.scripts.build || m("项目package.json文件scripts不存在命令build。")), t === Y.SERVER && (a?.scripts.build || m("项目package.json文件scripts不存在命令build。"));
|
|
1478
1481
|
}
|
|
1479
|
-
const
|
|
1482
|
+
const Nn = async () => {
|
|
1480
1483
|
const e = await Mt();
|
|
1481
1484
|
if (!e) {
|
|
1482
1485
|
m("未找到关联的禅道产品,请先关联禅道产品!");
|
|
1483
1486
|
return;
|
|
1484
1487
|
}
|
|
1485
|
-
const t = y("查询禅道执行中...").start(), a = await
|
|
1488
|
+
const t = y("查询禅道执行中...").start(), a = await js(Number(e.zenTaoProductId));
|
|
1486
1489
|
a.length || (t.fail("查询禅道执行失败"), m(`${e.name} 项目在禅道中未创建执行!`)), t.stop();
|
|
1487
|
-
const
|
|
1490
|
+
const n = await V({
|
|
1488
1491
|
message: "请选择执行",
|
|
1489
|
-
options: (
|
|
1492
|
+
options: (s) => {
|
|
1490
1493
|
const i = a.map((o) => ({
|
|
1491
1494
|
name: o.label,
|
|
1492
1495
|
value: o.value
|
|
1493
1496
|
}));
|
|
1494
|
-
return
|
|
1497
|
+
return s ? i.filter((o) => o.name.includes(s)) : i;
|
|
1495
1498
|
},
|
|
1496
1499
|
pageSize: 20,
|
|
1497
1500
|
loop: !0,
|
|
1498
1501
|
multiple: !1,
|
|
1499
1502
|
filter: !0
|
|
1500
1503
|
});
|
|
1501
|
-
t.start("创建或更新执行构建..."), await
|
|
1504
|
+
t.start("创建或更新执行构建..."), await Ts({
|
|
1502
1505
|
appName: e.name,
|
|
1503
|
-
executionId: Number(
|
|
1506
|
+
executionId: Number(n),
|
|
1504
1507
|
ldapAccount: I("ldapAccount")
|
|
1505
1508
|
}), t.succeed("创建或更新执行构建成功");
|
|
1506
|
-
},
|
|
1509
|
+
}, jn = [w.TEST, w.MASTER];
|
|
1507
1510
|
async function Bt(e, t) {
|
|
1508
1511
|
ee(), H();
|
|
1509
|
-
let a = e,
|
|
1510
|
-
const
|
|
1511
|
-
if (
|
|
1512
|
+
let a = e, n = t.platform;
|
|
1513
|
+
const s = W();
|
|
1514
|
+
if (s.language === $.JAVA && (n = Y.SERVER), a && !Object.values(w).includes(a) && m("仅支持发布指定环境分支"), n && !Object.values(Y).includes(n) && m("发布平台错误"), n || (n = await E({
|
|
1512
1515
|
message: "请选择平台",
|
|
1513
1516
|
choices: ka
|
|
1514
|
-
})),
|
|
1517
|
+
})), n === Y.NPM && (a = w.MASTER), !a) {
|
|
1515
1518
|
const l = await E({
|
|
1516
1519
|
message: "请选择部署环境",
|
|
1517
1520
|
choices: At
|
|
1518
1521
|
});
|
|
1519
1522
|
a = Ga(l);
|
|
1520
1523
|
}
|
|
1521
|
-
a === w.TEST && await
|
|
1524
|
+
a === w.TEST && await Nn();
|
|
1522
1525
|
let i = "";
|
|
1523
|
-
|
|
1526
|
+
s.language === $.JAVASCRIPT && (i = Ra);
|
|
1524
1527
|
const o = [];
|
|
1525
|
-
if (
|
|
1526
|
-
let l
|
|
1528
|
+
if (s.language === $.JAVASCRIPT) {
|
|
1529
|
+
let l;
|
|
1527
1530
|
const d = We();
|
|
1528
1531
|
d.name.startsWith("@") && d.name.includes("/") ? l = d.name.split("/").pop() || "" : l = d.name, l && o.push(l);
|
|
1529
1532
|
}
|
|
1530
|
-
if (
|
|
1531
|
-
const { projects: l } = await
|
|
1532
|
-
(g) =>
|
|
1533
|
+
if (s.language === $.JAVA) {
|
|
1534
|
+
const { projects: l } = await Ds(), d = l.find(
|
|
1535
|
+
(g) => se(g.url) === se(s.repository.url)
|
|
1533
1536
|
);
|
|
1534
1537
|
if (!d)
|
|
1535
1538
|
m("未找到项目对应的模块信息");
|
|
1536
1539
|
else {
|
|
1537
1540
|
i = d["k8s-group-name"];
|
|
1538
|
-
const g = d.modules.map(({ name:
|
|
1539
|
-
name: `${
|
|
1540
|
-
value:
|
|
1541
|
+
const g = d.modules.map(({ name: h, desc: v }) => ({
|
|
1542
|
+
name: `${h} (${v})`,
|
|
1543
|
+
value: h
|
|
1541
1544
|
}));
|
|
1542
1545
|
if (t.module) {
|
|
1543
|
-
const
|
|
1544
|
-
g.forEach((
|
|
1546
|
+
const h = new Set(t.module.split(Fe));
|
|
1547
|
+
g.forEach((v) => h.has(v.value) && o.push(v.value));
|
|
1545
1548
|
}
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1549
|
+
if (g.length === 1)
|
|
1550
|
+
!o.length && o.push(g[0].value);
|
|
1551
|
+
else {
|
|
1552
|
+
const h = await V({
|
|
1553
|
+
message: "请选择部署模块",
|
|
1554
|
+
options: (v) => v ? g.filter((G) => G.name.includes(v)) : g,
|
|
1555
|
+
pageSize: 20,
|
|
1556
|
+
loop: !0,
|
|
1557
|
+
clearInputWhenSelected: !0,
|
|
1558
|
+
multiple: !0,
|
|
1559
|
+
validate: (v) => !v.length && !o.length ? "请选择一个部署模块" : !0,
|
|
1560
|
+
filter: !0,
|
|
1561
|
+
theme: {
|
|
1562
|
+
style: {
|
|
1563
|
+
renderSelectedOptions: (v) => v.map((G, P) => `${P + 1}.${G.value}`).join(", ")
|
|
1564
|
+
}
|
|
1558
1565
|
}
|
|
1559
|
-
}
|
|
1560
|
-
|
|
1561
|
-
|
|
1566
|
+
});
|
|
1567
|
+
o.push(...h);
|
|
1568
|
+
}
|
|
1562
1569
|
}
|
|
1563
1570
|
}
|
|
1564
1571
|
let r = [];
|
|
1565
|
-
const c =
|
|
1572
|
+
const c = jn.includes(a);
|
|
1566
1573
|
!t.skipSelectionNotification && !c && (r = await Pt("请选择部署成功要通知的人员:", () => !0, !0));
|
|
1567
1574
|
let u = [];
|
|
1568
|
-
if (!t.skipGroupNotification && !c && (u = await
|
|
1569
|
-
const l = await
|
|
1575
|
+
if (!t.skipGroupNotification && !c && (u = await nn("请选择部署成功要通知的群组:", () => !0, !0)), c && !t.skipGroupNotification && !u.length) {
|
|
1576
|
+
const l = await bn();
|
|
1570
1577
|
l && u.push(l);
|
|
1571
1578
|
}
|
|
1572
|
-
if (
|
|
1579
|
+
if (s.language === $.JAVASCRIPT) {
|
|
1573
1580
|
const l = Fa(a);
|
|
1574
|
-
|
|
1581
|
+
Sn(l, n);
|
|
1575
1582
|
}
|
|
1576
|
-
await
|
|
1583
|
+
await An({
|
|
1577
1584
|
moduleNames: o,
|
|
1578
1585
|
k8sGroupName: i,
|
|
1579
1586
|
branchName: a,
|
|
@@ -1581,17 +1588,17 @@ async function Bt(e, t) {
|
|
|
1581
1588
|
notifyGroups: u
|
|
1582
1589
|
});
|
|
1583
1590
|
}
|
|
1584
|
-
async function zt(e, t, a,
|
|
1585
|
-
const
|
|
1591
|
+
async function zt(e, t, a, n) {
|
|
1592
|
+
const s = y(`分支合并中,${e} -> ${t}`).start();
|
|
1586
1593
|
let i = 0;
|
|
1587
1594
|
try {
|
|
1588
|
-
const { iid: r } = await
|
|
1595
|
+
const { iid: r } = await Zs({
|
|
1589
1596
|
title: `${e} -> ${t} by z-develop`,
|
|
1590
1597
|
id: a.id,
|
|
1591
1598
|
source_branch: e,
|
|
1592
1599
|
target_branch: t,
|
|
1593
1600
|
// 合到主分支上的分支需要在合并完成后被移除
|
|
1594
|
-
remove_source_branch:
|
|
1601
|
+
remove_source_branch: n ? !1 : w.MASTER === t
|
|
1595
1602
|
});
|
|
1596
1603
|
i = r;
|
|
1597
1604
|
} catch (r) {
|
|
@@ -1601,42 +1608,42 @@ async function zt(e, t, a, s) {
|
|
|
1601
1608
|
try {
|
|
1602
1609
|
await new Promise((r) => {
|
|
1603
1610
|
setTimeout(r, 5e3);
|
|
1604
|
-
}), await
|
|
1611
|
+
}), await Ks({
|
|
1605
1612
|
id: a.id,
|
|
1606
1613
|
iid: i
|
|
1607
|
-
}),
|
|
1614
|
+
}), s.succeed(`分支${e}已合并到分支${t}`);
|
|
1608
1615
|
} catch (r) {
|
|
1609
1616
|
me.isAxiosError(r) || m(r);
|
|
1610
1617
|
const c = r?.response?.status;
|
|
1611
1618
|
if (c === 406)
|
|
1612
1619
|
return await o();
|
|
1613
|
-
if (await
|
|
1620
|
+
if (await Ys({
|
|
1614
1621
|
id: a.id,
|
|
1615
1622
|
iid: i,
|
|
1616
1623
|
state_event: "close"
|
|
1617
1624
|
}), c === 405) {
|
|
1618
|
-
const u = await
|
|
1625
|
+
const u = await Xs({
|
|
1619
1626
|
id: a.id,
|
|
1620
1627
|
iid: i
|
|
1621
1628
|
});
|
|
1622
1629
|
if (u.merge_status === "cannot_be_merged" && u.diff_refs.base_sha === u.diff_refs.head_sha) {
|
|
1623
|
-
|
|
1630
|
+
s.warn("MR已关闭。判定为空的合并请求(没有新内容),可继续进行部署");
|
|
1624
1631
|
return;
|
|
1625
1632
|
}
|
|
1626
1633
|
}
|
|
1627
|
-
|
|
1634
|
+
s.fail("合并过程中出现冲突,MR已关闭。建议在本地完成合并。"), process.exit(1);
|
|
1628
1635
|
}
|
|
1629
1636
|
};
|
|
1630
1637
|
await o();
|
|
1631
1638
|
}
|
|
1632
|
-
async function
|
|
1633
|
-
const a = `origin/${e.sourceBranch}`,
|
|
1639
|
+
async function Tn(e, t) {
|
|
1640
|
+
const a = `origin/${e.sourceBranch}`, n = await p(`git log -b origin/${w.MASTER} -1 --format=%H`), s = await p(`git log -b origin/${e.sourceBranch} -1 --format=%H`);
|
|
1634
1641
|
await p(
|
|
1635
|
-
`git log ${
|
|
1642
|
+
`git log ${n}...${s} -b ${a}`
|
|
1636
1643
|
) || m(`分支${e.sourceBranch}上不存在新的commit,不需要合并。`), await p(
|
|
1637
|
-
`git branch --contains ${
|
|
1644
|
+
`git branch --contains ${n} -r ${a}`
|
|
1638
1645
|
) || (console.log(A.yellow("注意:当前分支上不存在远程主分支最新代码,将在自动合入后继续。")), await zt(w.MASTER, e.sourceBranch, e)), t === w.MASTER && (await p(
|
|
1639
|
-
`git cherry origin/${
|
|
1646
|
+
`git cherry origin/${D.TEST} ${a} origin/${w.MASTER}`
|
|
1640
1647
|
)).split(`
|
|
1641
1648
|
`).some((c) => c.startsWith("+ ")) && m("请先在测试环境发布要部署的代码");
|
|
1642
1649
|
}
|
|
@@ -1647,11 +1654,11 @@ const lt = async (e, t) => {
|
|
|
1647
1654
|
m(`合并到远程分支 ${e} 失败,${a}`);
|
|
1648
1655
|
}
|
|
1649
1656
|
};
|
|
1650
|
-
async function
|
|
1657
|
+
async function kn(e, t) {
|
|
1651
1658
|
ee(), H(), await ge();
|
|
1652
|
-
const a = await
|
|
1659
|
+
const a = await ss();
|
|
1653
1660
|
Object.values(w).includes(a.sourceBranch) && m(`当前分支${a.sourceBranch}不可作为源分支合并到目标分支。`);
|
|
1654
|
-
const
|
|
1661
|
+
const s = (await en(a.id)).filter((c) => ![a.sourceBranch].includes(c.name)).map((c) => {
|
|
1655
1662
|
let u = c.name;
|
|
1656
1663
|
return Object.values(w).includes(u) && (u = A.bold.blue(u)), {
|
|
1657
1664
|
name: u,
|
|
@@ -1659,9 +1666,9 @@ async function ks(e, t) {
|
|
|
1659
1666
|
};
|
|
1660
1667
|
});
|
|
1661
1668
|
let i;
|
|
1662
|
-
e && !
|
|
1669
|
+
e && !s.filter((c) => c.value === e).length && m(`未找到目标分支${e}`), e ? i = e : i = await E({
|
|
1663
1670
|
message: "请选择要合并到的目标分支:",
|
|
1664
|
-
choices:
|
|
1671
|
+
choices: s
|
|
1665
1672
|
});
|
|
1666
1673
|
const o = y(`本地分支${a.sourceBranch}检测中`).start();
|
|
1667
1674
|
if (await p(`git ls-remote --heads origin ${a.sourceBranch}`)) {
|
|
@@ -1672,7 +1679,7 @@ async function ks(e, t) {
|
|
|
1672
1679
|
), process.exit(1));
|
|
1673
1680
|
} else
|
|
1674
1681
|
await lt(a.sourceBranch, o);
|
|
1675
|
-
await
|
|
1682
|
+
await Tn(a, i), await zt(a.sourceBranch, i, a, t.keepBranchAfterMergeMaster), w.MASTER === i && !t.keepBranchAfterMergeMaster && (await p(`git checkout ${w.MASTER}`), await p(`git pull origin ${w.MASTER}`), await p(`git branch -d ${a.sourceBranch}`), U(
|
|
1676
1683
|
`${a.sourceBranch}分支已移除,当前已切换到最新的${w.MASTER}。如需继续开发,请检出新分支(z c b)。`
|
|
1677
1684
|
)), Object.values(w).includes(i) && await Bt(i, {
|
|
1678
1685
|
platform: t.deployPlatform,
|
|
@@ -1680,9 +1687,9 @@ async function ks(e, t) {
|
|
|
1680
1687
|
skipGroupNotification: t.skipGroupNotification
|
|
1681
1688
|
});
|
|
1682
1689
|
}
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
async function
|
|
1690
|
+
x.command("merge").alias("m").description("合并当前分支到指定远程分支,并部署。").argument("[branch]", "目标分支名称").option("--deploy-platform <platform>", `合并成功后要部署的平台。可选值:${Object.values(Y).join("/")}`).option("--deploy-skip-selection-notification", "部署时,是否跳过选择部署通知人环节").option("--skip-group-notification", "是否跳过选择部署通知群聊环节").option("--keep-branch-after-merge-master", "在合并到主分支之后,是否保留分支。默认否").action((...e) => M(kn, ...e));
|
|
1691
|
+
x.command("deploy").alias("d").description("部署到指定环境").argument("[branchName]", `部署环境。可选值:${Object.values(w).join("/")}`).option("--platform <platform>", `部署平台。可选值:${Object.values(Y).join("/")}`).option("--module <module>", "部署模块。Java项目适用,填入要部署的模块名称,多个使用逗号分隔").option("--skip-selection-notification", "是否跳过选择部署通知人环节").option("--skip-group-notification", "是否跳过选择部署通知群聊环节").action((...e) => M(Bt, ...e));
|
|
1692
|
+
async function En() {
|
|
1686
1693
|
try {
|
|
1687
1694
|
await p("java -jar ./.z/checkstyle.jar -c ./.z/checkstyle.xml .", {
|
|
1688
1695
|
silent: !1
|
|
@@ -1691,42 +1698,42 @@ async function Es() {
|
|
|
1691
1698
|
m("checkstyle执行出错"), process.exit(1);
|
|
1692
1699
|
}
|
|
1693
1700
|
}
|
|
1694
|
-
const Ie = "origin/",
|
|
1701
|
+
const Ie = "origin/", In = Object.values(w).map((e) => `${Ie}${e}`), Rn = Object.values(w), Ee = w.MASTER, Cn = async (e) => {
|
|
1695
1702
|
await p("git fetch --prune");
|
|
1696
1703
|
const t = `${Ie}${e}`, a = await p(`git branch -r --merged ${t}`, {
|
|
1697
1704
|
encoding: "utf8"
|
|
1698
|
-
}),
|
|
1705
|
+
}), n = await p(`git branch --merged ${t}`, {
|
|
1699
1706
|
encoding: "utf8"
|
|
1700
|
-
}),
|
|
1707
|
+
}), s = /* @__PURE__ */ new Map();
|
|
1701
1708
|
return a.split(`
|
|
1702
1709
|
`).forEach((i) => {
|
|
1703
1710
|
const o = i.trim();
|
|
1704
|
-
if (o && o !== t && !o.startsWith(`${Ie}HEAD`) && !
|
|
1711
|
+
if (o && o !== t && !o.startsWith(`${Ie}HEAD`) && !In.includes(o)) {
|
|
1705
1712
|
const r = o.replace(new RegExp(`^${Ie}`), "");
|
|
1706
|
-
|
|
1713
|
+
s.set(r, {
|
|
1707
1714
|
name: r,
|
|
1708
1715
|
value: r,
|
|
1709
|
-
hasLocal:
|
|
1716
|
+
hasLocal: s.get(r)?.hasLocal ?? !1,
|
|
1710
1717
|
hasRemote: !0
|
|
1711
1718
|
});
|
|
1712
1719
|
}
|
|
1713
|
-
}),
|
|
1720
|
+
}), n.split(`
|
|
1714
1721
|
`).forEach((i) => {
|
|
1715
1722
|
const o = i.replace(/^\*?\s*/, "").trim();
|
|
1716
|
-
if (o && o !== e && !
|
|
1717
|
-
const r =
|
|
1718
|
-
|
|
1723
|
+
if (o && o !== e && !Rn.includes(o)) {
|
|
1724
|
+
const r = s.get(o);
|
|
1725
|
+
s.set(o, {
|
|
1719
1726
|
name: o,
|
|
1720
1727
|
value: o,
|
|
1721
1728
|
hasLocal: !0,
|
|
1722
1729
|
hasRemote: r?.hasRemote ?? !1
|
|
1723
1730
|
});
|
|
1724
1731
|
}
|
|
1725
|
-
}), [...
|
|
1732
|
+
}), [...s.values()].map((i) => ({
|
|
1726
1733
|
...i,
|
|
1727
1734
|
name: `${i.value}${i.hasRemote && i.hasLocal ? "(本地/远程)" : i.hasRemote ? "(远程)" : "(本地)"}`
|
|
1728
1735
|
})).sort((i, o) => i.value.localeCompare(o.value));
|
|
1729
|
-
},
|
|
1736
|
+
}, Ln = (e) => V({
|
|
1730
1737
|
message: "请选择需要删除的分支",
|
|
1731
1738
|
options: (t) => t ? e.filter((a) => a.name.includes(t)) : e,
|
|
1732
1739
|
pageSize: 20,
|
|
@@ -1740,18 +1747,18 @@ const Ie = "origin/", Is = Object.values(w).map((e) => `${Ie}${e}`), Rs = Object
|
|
|
1740
1747
|
renderSelectedOptions: (t) => t.map((a) => a.value).join(", ")
|
|
1741
1748
|
}
|
|
1742
1749
|
}
|
|
1743
|
-
}),
|
|
1750
|
+
}), xn = async (e) => (await p(`git branch --list ${e}`)).trim() !== "", Pn = (e) => {
|
|
1744
1751
|
Ve(`git push origin --delete ${e}`);
|
|
1745
|
-
},
|
|
1752
|
+
}, Dn = (e) => {
|
|
1746
1753
|
Ve(`git branch -d ${e}`);
|
|
1747
|
-
},
|
|
1754
|
+
}, On = async () => {
|
|
1748
1755
|
await ge();
|
|
1749
|
-
const e = y(`正在查询本地和远程已经合并到${Ee}的分支...`).start(), t = await
|
|
1756
|
+
const e = y(`正在查询本地和远程已经合并到${Ee}的分支...`).start(), t = await Cn(Ee);
|
|
1750
1757
|
if (e.succeed(`查询到 ${t.length} 个已合并到 ${Ee} 的分支`), !t.length) {
|
|
1751
1758
|
J(`未查询到已合并到 ${Ee} 的可删除分支`);
|
|
1752
1759
|
return;
|
|
1753
1760
|
}
|
|
1754
|
-
const a = await
|
|
1761
|
+
const a = await Ln(t);
|
|
1755
1762
|
if (!await Le({
|
|
1756
1763
|
message: `确认删除选中的 ${a.length} 个分支对应的远程分支和本地分支?`,
|
|
1757
1764
|
default: !1
|
|
@@ -1759,21 +1766,21 @@ const Ie = "origin/", Is = Object.values(w).map((e) => `${Ie}${e}`), Rs = Object
|
|
|
1759
1766
|
J("已取消删除");
|
|
1760
1767
|
return;
|
|
1761
1768
|
}
|
|
1762
|
-
const
|
|
1769
|
+
const s = await p("git branch --show-current"), i = [], o = [], r = [], c = t.filter((l) => a.includes(l.value)), u = y("正在删除分支...").start();
|
|
1763
1770
|
try {
|
|
1764
1771
|
for (const l of c) {
|
|
1765
1772
|
const { value: d, hasLocal: g, hasRemote: h } = l;
|
|
1766
|
-
if (h && (u.text = `正在删除远程分支 ${d}...`,
|
|
1773
|
+
if (h && (u.text = `正在删除远程分支 ${d}...`, Pn(d), o.push(d)), d === s) {
|
|
1767
1774
|
g && i.push(d);
|
|
1768
1775
|
continue;
|
|
1769
1776
|
}
|
|
1770
|
-
!g || !await
|
|
1777
|
+
!g || !await xn(d) || (u.text = `正在删除本地分支 ${d}...`, Dn(d), r.push(d));
|
|
1771
1778
|
}
|
|
1772
1779
|
} catch (l) {
|
|
1773
1780
|
throw u.fail("删除分支失败"), l;
|
|
1774
1781
|
}
|
|
1775
1782
|
u.succeed("分支删除完成"), o.length && U(`远程分支删除完成:${o.join(", ")}`), r.length && U(`本地分支删除完成:${r.join(", ")}`), i.length && J(`${i.join(", ")} 为当前分支,无法删除本地分支`);
|
|
1776
|
-
}, _t = "0000000000000000000000000000000000000000", ut = "refs/heads/",
|
|
1783
|
+
}, _t = "0000000000000000000000000000000000000000", ut = "refs/heads/", Mn = async (e, t) => {
|
|
1777
1784
|
if (t === _t) {
|
|
1778
1785
|
try {
|
|
1779
1786
|
const a = await p(`git rev-parse --verify --quiet origin/${w.MASTER}`);
|
|
@@ -1784,48 +1791,48 @@ const Ie = "origin/", Is = Object.values(w).map((e) => `${Ie}${e}`), Rs = Object
|
|
|
1784
1791
|
return null;
|
|
1785
1792
|
}
|
|
1786
1793
|
return `${t}..${e}`;
|
|
1787
|
-
},
|
|
1794
|
+
}, Bn = async (e) => {
|
|
1788
1795
|
try {
|
|
1789
1796
|
return (await p(`git log ${e} --grep="(cherry picked from commit" --format="%H"`)).split(`
|
|
1790
1797
|
`).filter(Boolean);
|
|
1791
1798
|
} catch {
|
|
1792
1799
|
return [];
|
|
1793
1800
|
}
|
|
1794
|
-
},
|
|
1801
|
+
}, zn = async (e) => {
|
|
1795
1802
|
try {
|
|
1796
1803
|
return (await p(`git log ${e} --format="%H %at %ct"`)).split(`
|
|
1797
1804
|
`).flatMap((a) => {
|
|
1798
|
-
const [
|
|
1799
|
-
return
|
|
1805
|
+
const [n, s, i] = a.split(" ");
|
|
1806
|
+
return n && s !== i ? [n] : [];
|
|
1800
1807
|
});
|
|
1801
1808
|
} catch {
|
|
1802
1809
|
return [];
|
|
1803
1810
|
}
|
|
1804
|
-
},
|
|
1811
|
+
}, _n = async () => {
|
|
1805
1812
|
const { skipGitPushLimit: e } = W(), t = Object.values(w), a = dt(0, "utf-8");
|
|
1806
1813
|
if (!a)
|
|
1807
1814
|
return;
|
|
1808
|
-
const
|
|
1809
|
-
`),
|
|
1810
|
-
for (let i = 0; i <
|
|
1811
|
-
const [, o, r, c] =
|
|
1815
|
+
const n = a.trim().split(`
|
|
1816
|
+
`), s = n.length;
|
|
1817
|
+
for (let i = 0; i < s; i++) {
|
|
1818
|
+
const [, o, r, c] = n[i].split(/\s+/);
|
|
1812
1819
|
if (!r.startsWith(ut) || o === _t)
|
|
1813
1820
|
continue;
|
|
1814
1821
|
const u = r.replace(ut, "");
|
|
1815
1822
|
!e && t.includes(u) && m(`禁止直接 Push 到环境分支:${u}`);
|
|
1816
|
-
const l = await
|
|
1823
|
+
const l = await Mn(o, c);
|
|
1817
1824
|
if (!l)
|
|
1818
1825
|
continue;
|
|
1819
1826
|
const [d, g] = await Promise.all([
|
|
1820
|
-
|
|
1821
|
-
|
|
1827
|
+
Bn(l),
|
|
1828
|
+
zn(l)
|
|
1822
1829
|
]), h = [.../* @__PURE__ */ new Set([...d, ...g])];
|
|
1823
1830
|
h.length > 0 && m(`以下提交中检测到包含 cherry-pick 特征,本次 Push 已被拒绝
|
|
1824
1831
|
${h.join(`
|
|
1825
1832
|
`)}`);
|
|
1826
1833
|
}
|
|
1827
1834
|
};
|
|
1828
|
-
async function
|
|
1835
|
+
async function Fn() {
|
|
1829
1836
|
j(f.resolve("node_modules", ".bin", "markdownlint")) || m("该项目未安装markdownlint,请安装后重试");
|
|
1830
1837
|
const e = y("markdownlint执行中...").start();
|
|
1831
1838
|
try {
|
|
@@ -1836,26 +1843,26 @@ async function Fs() {
|
|
|
1836
1843
|
e.fail("markdownlint校验出错"), process.exit(1);
|
|
1837
1844
|
}
|
|
1838
1845
|
}
|
|
1839
|
-
const
|
|
1846
|
+
const Gn = () => {
|
|
1840
1847
|
m("禁止执行 rebase,请使用 git merge!");
|
|
1841
1848
|
};
|
|
1842
|
-
function
|
|
1849
|
+
function Jn() {
|
|
1843
1850
|
const e = W();
|
|
1844
1851
|
if (e["lint-staged"])
|
|
1845
1852
|
return e["lint-staged"];
|
|
1846
1853
|
throw new Error("未找到lint配置");
|
|
1847
1854
|
}
|
|
1848
|
-
async function
|
|
1855
|
+
async function Un() {
|
|
1849
1856
|
const e = y("代码风格检测中...").start();
|
|
1850
1857
|
await da({
|
|
1851
1858
|
concurrent: 4,
|
|
1852
1859
|
debug: !1,
|
|
1853
|
-
config:
|
|
1860
|
+
config: Jn(),
|
|
1854
1861
|
quiet: !0,
|
|
1855
1862
|
relative: !0
|
|
1856
1863
|
}) ? (e.succeed("代码风格检测通过!"), process.exit(0)) : (e.fail("代码风格检测未通过!"), process.exit(1));
|
|
1857
1864
|
}
|
|
1858
|
-
function
|
|
1865
|
+
function Vn(e) {
|
|
1859
1866
|
if (e.includes("Merge") && e.includes("# Conflicts:") || fa.valid(e))
|
|
1860
1867
|
return !0;
|
|
1861
1868
|
const t = e.split(": ");
|
|
@@ -1864,11 +1871,11 @@ function Vs(e) {
|
|
|
1864
1871
|
const a = t[0];
|
|
1865
1872
|
return /^(feat|fix|refactor)/.test(a) ? /\(\d+(?:,\d+)*\)/.test(a) ? !0 : "ID缺少或者格式不正确。" : /^(chore|ci)/.test(a) ? [T.CHORE, T.CI].includes(a) ? !0 : "chore/ci类型无需填写ID。" : T.Break === a ? !0 : "不存在的提交类型。";
|
|
1866
1873
|
}
|
|
1867
|
-
async function
|
|
1868
|
-
const e = await _e(f.resolve(".git", "COMMIT_EDITMSG"), "utf-8"), t = y("提交信息格式校验中...").start(), a =
|
|
1874
|
+
async function Wn() {
|
|
1875
|
+
const e = await _e(f.resolve(".git", "COMMIT_EDITMSG"), "utf-8"), t = y("提交信息格式校验中...").start(), a = Vn(e);
|
|
1869
1876
|
a === !0 ? (t.succeed("提交信息格式校验通过"), process.exit(0)) : (t.fail(`提交信息格式校验失败。${a}`), process.exit(1));
|
|
1870
1877
|
}
|
|
1871
|
-
async function
|
|
1878
|
+
async function Hn() {
|
|
1872
1879
|
await ge();
|
|
1873
1880
|
const e = await ga({
|
|
1874
1881
|
// 分组,展示仓库链接
|
|
@@ -1882,12 +1889,12 @@ async function Hs() {
|
|
|
1882
1889
|
});
|
|
1883
1890
|
if (e && Object.keys(e).length) {
|
|
1884
1891
|
U("升级完成 🎉");
|
|
1885
|
-
const t = Object.entries(e).map(([a,
|
|
1892
|
+
const t = Object.entries(e).map(([a, n]) => `${a}@${n}`).join("; ");
|
|
1886
1893
|
await p(`git add . && git commit -m "chore: 依赖升级。${t}"`);
|
|
1887
1894
|
}
|
|
1888
1895
|
process.exit(0);
|
|
1889
1896
|
}
|
|
1890
|
-
async function
|
|
1897
|
+
async function qn(e) {
|
|
1891
1898
|
j(f.resolve("node_modules", ".bin", "eslint")) || m("该项目未安装eslint,请安装后重试");
|
|
1892
1899
|
const t = y("eslint执行中...").start();
|
|
1893
1900
|
try {
|
|
@@ -1899,7 +1906,7 @@ async function qs(e) {
|
|
|
1899
1906
|
t.fail("eslint校验出错"), process.exit(1);
|
|
1900
1907
|
}
|
|
1901
1908
|
}
|
|
1902
|
-
async function
|
|
1909
|
+
async function Zn() {
|
|
1903
1910
|
j(f.resolve("node_modules", ".bin", "prettier")) || m("该项目未安装prettier,请安装后重试");
|
|
1904
1911
|
const e = y("prettier执行中...").start();
|
|
1905
1912
|
try {
|
|
@@ -1913,10 +1920,10 @@ async function Zs() {
|
|
|
1913
1920
|
e.fail("prettier校验出错"), process.exit(1);
|
|
1914
1921
|
}
|
|
1915
1922
|
}
|
|
1916
|
-
function
|
|
1923
|
+
function Kn() {
|
|
1917
1924
|
j(f.resolve("./node_modules/.bin/vue-tsc")) || m("请先安装vue-tsc。推荐命令: npm i -D vue-tsc"), Ve("npx vue-tsc --build"), process.exit(0);
|
|
1918
1925
|
}
|
|
1919
|
-
const
|
|
1926
|
+
const Yn = [
|
|
1920
1927
|
[
|
|
1921
1928
|
"cm",
|
|
1922
1929
|
"commit-msg"
|
|
@@ -1972,7 +1979,7 @@ const Ys = [
|
|
|
1972
1979
|
"detect-push"
|
|
1973
1980
|
/* DetectPush */
|
|
1974
1981
|
]
|
|
1975
|
-
],
|
|
1982
|
+
], Xn = {
|
|
1976
1983
|
[$.JAVA]: [
|
|
1977
1984
|
{
|
|
1978
1985
|
name: "执行 check-style",
|
|
@@ -2019,30 +2026,30 @@ const Ys = [
|
|
|
2019
2026
|
/* DependencyCheck */
|
|
2020
2027
|
}
|
|
2021
2028
|
]
|
|
2022
|
-
},
|
|
2023
|
-
"commit-msg":
|
|
2024
|
-
"commit-files":
|
|
2025
|
-
prettier:
|
|
2026
|
-
eslint:
|
|
2027
|
-
"type-check":
|
|
2028
|
-
"dependency-check":
|
|
2029
|
-
checkstyle:
|
|
2030
|
-
"markdown-lint":
|
|
2031
|
-
"delete-merged":
|
|
2032
|
-
"not-allow-rebase":
|
|
2033
|
-
"detect-push":
|
|
2029
|
+
}, Qn = (e) => Reflect.get(Xn, e) ?? [], ei = {
|
|
2030
|
+
"commit-msg": Wn,
|
|
2031
|
+
"commit-files": Un,
|
|
2032
|
+
prettier: Zn,
|
|
2033
|
+
eslint: qn,
|
|
2034
|
+
"type-check": Kn,
|
|
2035
|
+
"dependency-check": Hn,
|
|
2036
|
+
checkstyle: En,
|
|
2037
|
+
"markdown-lint": Fn,
|
|
2038
|
+
"delete-merged": On,
|
|
2039
|
+
"not-allow-rebase": Gn,
|
|
2040
|
+
"detect-push": _n
|
|
2034
2041
|
}, ti = async (e, t) => {
|
|
2035
2042
|
const a = Reflect.get(ei, e);
|
|
2036
2043
|
a && typeof a == "function" && await a(t);
|
|
2037
2044
|
}, ai = (e) => {
|
|
2038
|
-
for (const [t, a] of
|
|
2045
|
+
for (const [t, a] of Yn)
|
|
2039
2046
|
if (e === t || e === a)
|
|
2040
2047
|
return a;
|
|
2041
2048
|
m("参数输入错误");
|
|
2042
2049
|
};
|
|
2043
|
-
async function
|
|
2050
|
+
async function si(e, t) {
|
|
2044
2051
|
ee(), H();
|
|
2045
|
-
const a = W(),
|
|
2052
|
+
const a = W(), n = e ? ai(e) : await E({
|
|
2046
2053
|
message: "请选择你要执行的操作",
|
|
2047
2054
|
choices: [
|
|
2048
2055
|
{
|
|
@@ -2050,7 +2057,7 @@ async function ni(e, t) {
|
|
|
2050
2057
|
value: "prettier"
|
|
2051
2058
|
/* Prettier */
|
|
2052
2059
|
},
|
|
2053
|
-
...
|
|
2060
|
+
...Qn(a.language),
|
|
2054
2061
|
{
|
|
2055
2062
|
name: "执行 delete-merged",
|
|
2056
2063
|
value: "delete-merged"
|
|
@@ -2058,19 +2065,19 @@ async function ni(e, t) {
|
|
|
2058
2065
|
}
|
|
2059
2066
|
]
|
|
2060
2067
|
});
|
|
2061
|
-
await ti(
|
|
2068
|
+
await ti(n, t);
|
|
2062
2069
|
}
|
|
2063
|
-
|
|
2070
|
+
x.command("run").alias("r").description("执行 eslint / prettier / type-check / dependency-check / checkstyle / markdown-lint / delete-merged。").argument(
|
|
2064
2071
|
"[type]",
|
|
2065
2072
|
"非必填。可选值为commit-msg|cm, commit-files|cf, prettier|p, eslint|e, type-check|tc, dependency-check|dc, checkstyle|cs, markdown-lint|ml, delete-merged|dm。"
|
|
2066
|
-
).option("--quiet", "eslint只打印error").option("--max-warnings [VALUE]", "eslint结果warn超过多少个会异常退出,默认为100", parseInt).action((...e) =>
|
|
2073
|
+
).option("--quiet", "eslint只打印error").option("--max-warnings [VALUE]", "eslint结果warn超过多少个会异常退出,默认为100", parseInt).action((...e) => M(si, ...e));
|
|
2067
2074
|
async function Ft(e = "latest") {
|
|
2068
2075
|
const t = y("安装中...").start();
|
|
2069
2076
|
await p(`npm i -g ${ce.name}@${e} --registry https://registry.npmmirror.com/`), t.text = "本地配置更新中...", de("latestCheckVersionTimestamp", Date.now()), de("version", e);
|
|
2070
2077
|
const a = await He();
|
|
2071
2078
|
De(a), X(), t.succeed(`升级完成,当前版本${e}`), process.exit(0);
|
|
2072
2079
|
}
|
|
2073
|
-
|
|
2080
|
+
x.command("update").alias("u").description("升级").argument("[version]", "版本号", "latest").action((...e) => M(Ft, ...e));
|
|
2074
2081
|
const Ke = /Thumbs\.db|\.git|DS_Store|idea/, Gt = "testcase";
|
|
2075
2082
|
function Jt(e) {
|
|
2076
2083
|
const t = e.match(/^(.*[^[])?\[(\d+)]$/);
|
|
@@ -2092,13 +2099,13 @@ function Jt(e) {
|
|
|
2092
2099
|
};
|
|
2093
2100
|
}
|
|
2094
2101
|
async function ie(e, t = {}) {
|
|
2095
|
-
const { exclude: a = Ke } = t,
|
|
2096
|
-
async function
|
|
2102
|
+
const { exclude: a = Ke } = t, n = [];
|
|
2103
|
+
async function s(i) {
|
|
2097
2104
|
const o = f.basename(i);
|
|
2098
|
-
if ((await
|
|
2105
|
+
if ((await na(i)).isFile())
|
|
2099
2106
|
return null;
|
|
2100
2107
|
const c = await Ue(i, { withFileTypes: !0 }), u = (await Promise.all(
|
|
2101
|
-
c.filter((v) => v.isDirectory() && !a.test(v.name)).map((v) =>
|
|
2108
|
+
c.filter((v) => v.isDirectory() && !a.test(v.name)).map((v) => s(f.join(i, v.name)))
|
|
2102
2109
|
)).filter(Boolean), { type: l, id: d, displayName: g } = Jt(o), h = {
|
|
2103
2110
|
name: o,
|
|
2104
2111
|
id: d,
|
|
@@ -2107,19 +2114,19 @@ async function ie(e, t = {}) {
|
|
|
2107
2114
|
type: l,
|
|
2108
2115
|
children: u
|
|
2109
2116
|
};
|
|
2110
|
-
return (t.hasRoot || f.resolve(e) !== i) &&
|
|
2117
|
+
return (t.hasRoot || f.resolve(e) !== i) && n.push(h), h;
|
|
2111
2118
|
}
|
|
2112
|
-
return await
|
|
2119
|
+
return await s(f.resolve(e)), n;
|
|
2113
2120
|
}
|
|
2114
2121
|
async function Ut(e, t = {}) {
|
|
2115
2122
|
const { exclude: a = Ke } = t;
|
|
2116
2123
|
try {
|
|
2117
|
-
const
|
|
2124
|
+
const n = await Ue(f.resolve(e), { withFileTypes: !0 });
|
|
2118
2125
|
return await Promise.all(
|
|
2119
|
-
|
|
2120
|
-
const i = f.join(e,
|
|
2126
|
+
n.filter((s) => s.isDirectory() && !a.test(s.name)).map((s) => {
|
|
2127
|
+
const i = f.join(e, s.name), { type: o, id: r, displayName: c } = Jt(s.name);
|
|
2121
2128
|
return {
|
|
2122
|
-
name:
|
|
2129
|
+
name: s.name,
|
|
2123
2130
|
id: r,
|
|
2124
2131
|
displayName: c,
|
|
2125
2132
|
path: i,
|
|
@@ -2127,8 +2134,8 @@ async function Ut(e, t = {}) {
|
|
|
2127
2134
|
};
|
|
2128
2135
|
})
|
|
2129
2136
|
);
|
|
2130
|
-
} catch (
|
|
2131
|
-
return m(`读取目录失败: ${e} : ${
|
|
2137
|
+
} catch (n) {
|
|
2138
|
+
return m(`读取目录失败: ${e} : ${n}`), [];
|
|
2132
2139
|
}
|
|
2133
2140
|
}
|
|
2134
2141
|
function Q(e, t, a) {
|
|
@@ -2141,29 +2148,29 @@ function Q(e, t, a) {
|
|
|
2141
2148
|
return t;
|
|
2142
2149
|
}
|
|
2143
2150
|
}
|
|
2144
|
-
async function je(e, t, a,
|
|
2151
|
+
async function je(e, t, a, n) {
|
|
2145
2152
|
try {
|
|
2146
|
-
const
|
|
2147
|
-
if (
|
|
2153
|
+
const s = f.basename(e), i = Q(a, t, n);
|
|
2154
|
+
if (s === i)
|
|
2148
2155
|
return !0;
|
|
2149
2156
|
const o = f.dirname(e), r = f.join(o, i);
|
|
2150
2157
|
return await Ja(e) ? await ft(e, r) : (await p(`git mv "${e}" "${r}"`), await p("git add .")), !0;
|
|
2151
|
-
} catch (
|
|
2152
|
-
return m(`重命名文件夹失败: ${e} -> ${t}。${
|
|
2158
|
+
} catch (s) {
|
|
2159
|
+
return m(`重命名文件夹失败: ${e} -> ${t}。${s}`), !1;
|
|
2153
2160
|
}
|
|
2154
2161
|
}
|
|
2155
|
-
async function
|
|
2156
|
-
const { exclude:
|
|
2157
|
-
async function
|
|
2162
|
+
async function ni(e, t, a = {}) {
|
|
2163
|
+
const { exclude: n = Ke } = a;
|
|
2164
|
+
async function s(i, o) {
|
|
2158
2165
|
if (!i || i.length === 0) return;
|
|
2159
|
-
const r = await Ut(o, { exclude:
|
|
2166
|
+
const r = await Ut(o, { exclude: n });
|
|
2160
2167
|
for (const c of i) {
|
|
2161
2168
|
const u = String(c.value), l = Q("module", c.label, u), d = r.find((h) => h.id === u);
|
|
2162
2169
|
let g = d?.path || f.join(o, l);
|
|
2163
|
-
d ? d.displayName !== c.label && await je(d.path, c.label, "module", u) && (g = f.join(o, l)) : (await fe(g, { recursive: !0 }), await p(`git add "${g}"`)), c.children && c.children.length > 0 && await
|
|
2170
|
+
d ? d.displayName !== c.label && await je(d.path, c.label, "module", u) && (g = f.join(o, l)) : (await fe(g, { recursive: !0 }), await p(`git add "${g}"`)), c.children && c.children.length > 0 && await s(c.children, g);
|
|
2164
2171
|
}
|
|
2165
2172
|
}
|
|
2166
|
-
await
|
|
2173
|
+
await s(e, f.resolve(t));
|
|
2167
2174
|
}
|
|
2168
2175
|
async function Vt(e) {
|
|
2169
2176
|
const t = {
|
|
@@ -2174,16 +2181,16 @@ async function Vt(e) {
|
|
|
2174
2181
|
if (e)
|
|
2175
2182
|
Number.isNaN(Number(e)) && m("请输入正确的产品ID"), t.id = Number(e);
|
|
2176
2183
|
else {
|
|
2177
|
-
const a = await
|
|
2184
|
+
const a = await rs();
|
|
2178
2185
|
t.id = await E({
|
|
2179
2186
|
message: "请选择产品",
|
|
2180
|
-
choices: a.map((
|
|
2181
|
-
name: `${
|
|
2182
|
-
value:
|
|
2187
|
+
choices: a.map((n) => ({
|
|
2188
|
+
name: `${n.label}[${n.value}]`,
|
|
2189
|
+
value: n.value
|
|
2183
2190
|
}))
|
|
2184
2191
|
});
|
|
2185
2192
|
}
|
|
2186
|
-
return t.name = await
|
|
2193
|
+
return t.name = await os(t.id), t.path = f.join(Gt, Q("module", t.name, String(t.id))), t;
|
|
2187
2194
|
}
|
|
2188
2195
|
async function Ye(e) {
|
|
2189
2196
|
return (await Ut(Gt)).find((a) => Number(a.id) === e.id);
|
|
@@ -2194,26 +2201,26 @@ async function Wt(e, t) {
|
|
|
2194
2201
|
priority: e.pri,
|
|
2195
2202
|
steps: []
|
|
2196
2203
|
};
|
|
2197
|
-
a.steps = await
|
|
2204
|
+
a.steps = await ls(e.id), C.writeJSONSync(t, a, {
|
|
2198
2205
|
spaces: 2
|
|
2199
2206
|
});
|
|
2200
2207
|
}
|
|
2201
2208
|
async function Ht(e, t) {
|
|
2202
2209
|
await fe(t, {
|
|
2203
2210
|
recursive: !0
|
|
2204
|
-
}), await Wt(e, f.join(t, "config.json")),
|
|
2211
|
+
}), await Wt(e, f.join(t, "config.json")), C.ensureFileSync(f.join(t, "data.yaml")), await z(
|
|
2205
2212
|
f.join(t, "data.yaml"),
|
|
2206
|
-
j(f.resolve(K, "data.yaml")) ? await _e(f.resolve(K, "data.yaml")) : await
|
|
2207
|
-
),
|
|
2213
|
+
j(f.resolve(K, "data.yaml")) ? await _e(f.resolve(K, "data.yaml")) : await Fs()
|
|
2214
|
+
), C.ensureFileSync(f.join(t, "main.py")), await z(
|
|
2208
2215
|
f.join(t, "main.py"),
|
|
2209
|
-
j(f.resolve(K, "main.py")) ? await _e(f.resolve(K, "main.py")) : await
|
|
2216
|
+
j(f.resolve(K, "main.py")) ? await _e(f.resolve(K, "main.py")) : await Gs()
|
|
2210
2217
|
);
|
|
2211
2218
|
}
|
|
2212
2219
|
function Xe(e) {
|
|
2213
2220
|
if (e) {
|
|
2214
2221
|
const t = e.split(",").map((a) => a.trim()).filter((a) => {
|
|
2215
|
-
const
|
|
2216
|
-
return Number.isInteger(
|
|
2222
|
+
const n = Number(a);
|
|
2223
|
+
return Number.isInteger(n) && n > 0;
|
|
2217
2224
|
}).map((a) => Number(a));
|
|
2218
2225
|
return t.length === 0 ? (m('未找到有效的ID,请输入格式如 "1,2,3,4" 的正整数ID'), []) : t;
|
|
2219
2226
|
}
|
|
@@ -2222,14 +2229,14 @@ function Xe(e) {
|
|
|
2222
2229
|
async function Oe(e, t) {
|
|
2223
2230
|
ee(), H(), await ge();
|
|
2224
2231
|
let a;
|
|
2225
|
-
t ? ([
|
|
2232
|
+
t ? ([R.MODULE, R.CASE].includes(t) || m(`不支持的参数${t}。参数值应为 ${R.MODULE} 或者 ${R.CASE}。`), a = t) : a = await E({
|
|
2226
2233
|
message: `请选择要${e}的数据类型`,
|
|
2227
2234
|
choices: Ca
|
|
2228
2235
|
});
|
|
2229
|
-
const
|
|
2236
|
+
const n = a === R.MODULE ? "模块" : R.CASE === a ? "用例" : "";
|
|
2230
2237
|
return {
|
|
2231
2238
|
type: a,
|
|
2232
|
-
typeStr:
|
|
2239
|
+
typeStr: n
|
|
2233
2240
|
};
|
|
2234
2241
|
}
|
|
2235
2242
|
async function Me(e) {
|
|
@@ -2241,10 +2248,10 @@ async function Me(e) {
|
|
|
2241
2248
|
}
|
|
2242
2249
|
async function ii(e, t, a) {
|
|
2243
2250
|
e.text = "查找本地产品目录...", await Ye(t) || m(`本地未找到产品【${t.name}[${t.id}]】`), e.text = "解析ID参数...";
|
|
2244
|
-
const
|
|
2251
|
+
const s = Xe(a);
|
|
2245
2252
|
let i = await ie(t.path);
|
|
2246
2253
|
e.text = "获取远程用例列表...";
|
|
2247
|
-
const o = await
|
|
2254
|
+
const o = await cs(t.id, s);
|
|
2248
2255
|
e.text = "本地用例同步中...";
|
|
2249
2256
|
for (const r of o) {
|
|
2250
2257
|
let c;
|
|
@@ -2266,106 +2273,106 @@ async function ri(e, t) {
|
|
|
2266
2273
|
e.text = "本地产品目录查找中...";
|
|
2267
2274
|
const a = await Ye(t);
|
|
2268
2275
|
a ? (e.text = "找到产品目录。开始重命名...", a.displayName !== t.name && await je(a.path, t.name, a.type, a.id) && (e.text = `重命名成功: ${a.displayName} -> ${t.name}`)) : (e.text = "未找到。开始创建产品目录...", await fe(t.path, { recursive: !0 }), await p("git add .")), e.text = "获取远程模块列表...";
|
|
2269
|
-
const
|
|
2270
|
-
e.text = "本地同步模块中...", await
|
|
2276
|
+
const n = await Rt(t.id);
|
|
2277
|
+
e.text = "本地同步模块中...", await ni(n || [], t.path);
|
|
2271
2278
|
}
|
|
2272
2279
|
async function oi(e, t) {
|
|
2273
|
-
const { type: a, typeStr:
|
|
2274
|
-
if (
|
|
2280
|
+
const { type: a, typeStr: n } = await Oe("拉取", e), s = await Vt(t.productId), i = y(`${n}同步中...`).start();
|
|
2281
|
+
if (R.MODULE === a && await ri(i, s), R.CASE === a && await ii(i, s, t.caseIds), i.succeed(`${n}同步完成 🎉`), !t.disableAutoCommit && await p("git status -s")) {
|
|
2275
2282
|
const o = y("代码提交中...").start();
|
|
2276
2283
|
try {
|
|
2277
|
-
await p(`git add . && git commit -m "chore: 同步禅道${
|
|
2284
|
+
await p(`git add . && git commit -m "chore: 同步禅道${n}数据"`), o.succeed("代码已提交 ✅");
|
|
2278
2285
|
} catch (r) {
|
|
2279
2286
|
o.fail(`提交失败,${r}`), process.exit(1);
|
|
2280
2287
|
}
|
|
2281
2288
|
}
|
|
2282
2289
|
}
|
|
2283
|
-
|
|
2290
|
+
x.command("qa-pull").alias("qp").description("将禅道中的模块或者用例同步到本地").argument("[type]", "可选值为module/case").option("--product-id <productId>", "指定产品ID").option("--case-ids <caseIds>", "type=case时,可传指定用例ID(可传N个,逗号隔开);不传则为产品下全部用例").option("--disable-auto-commit", "是否跳过自动将修改结果提交。").action((...e) => M(oi, ...e));
|
|
2284
2291
|
async function ci(e, t, a) {
|
|
2285
|
-
let
|
|
2292
|
+
let n = await _({
|
|
2286
2293
|
message: "请输入你要创建的用例的前置条件(可不填)"
|
|
2287
2294
|
});
|
|
2288
|
-
|
|
2289
|
-
const
|
|
2290
|
-
|
|
2291
|
-
const i = await
|
|
2295
|
+
n = n.trim();
|
|
2296
|
+
const s = y(`用例【${a}】开始创建...`).start();
|
|
2297
|
+
s.text = "远程用例创建中...";
|
|
2298
|
+
const i = await ps({
|
|
2292
2299
|
product: Number(e.id),
|
|
2293
2300
|
// 如果父模块是产品根目录,parent=0
|
|
2294
2301
|
module: f.resolve(e?.path) === t?.path ? 0 : Number(t?.id || 0),
|
|
2295
2302
|
title: a,
|
|
2296
2303
|
type: "interface",
|
|
2297
2304
|
openedBy: I("ldapAccount"),
|
|
2298
|
-
precondition:
|
|
2305
|
+
precondition: n || ""
|
|
2299
2306
|
});
|
|
2300
|
-
|
|
2307
|
+
s.text = "远程用例步骤创建中...", await ms({
|
|
2301
2308
|
case: i,
|
|
2302
2309
|
type: "step",
|
|
2303
2310
|
desc: "按照预期执行",
|
|
2304
2311
|
expect: "正常执行,符合预期"
|
|
2305
|
-
}),
|
|
2312
|
+
}), s.text = "本地用例创建中...";
|
|
2306
2313
|
const o = f.join(t.path, Q("case", a, String(i)));
|
|
2307
2314
|
return j(o) ? U(`${o}已存在,请检查是否对应,本地不再创建。`) : (await Ht(
|
|
2308
2315
|
{
|
|
2309
2316
|
id: i,
|
|
2310
2317
|
pri: 3,
|
|
2311
|
-
precondition:
|
|
2318
|
+
precondition: n
|
|
2312
2319
|
},
|
|
2313
2320
|
o
|
|
2314
|
-
),
|
|
2321
|
+
), s.succeed(`用例【[${o}】创建完成 🎉`), o);
|
|
2315
2322
|
}
|
|
2316
2323
|
async function li(e, t, a) {
|
|
2317
|
-
const
|
|
2318
|
-
|
|
2319
|
-
const
|
|
2324
|
+
const n = y(`模块【${a}】开始创建...`).start();
|
|
2325
|
+
n.text = "远程模块创建中...";
|
|
2326
|
+
const s = await us({
|
|
2320
2327
|
root: Number(e.id),
|
|
2321
2328
|
name: a,
|
|
2322
2329
|
// 如果父模块是产品根目录,parent=0
|
|
2323
2330
|
parent: f.resolve(e?.path) === t?.path ? 0 : Number(t?.id || 0)
|
|
2324
2331
|
});
|
|
2325
|
-
|
|
2326
|
-
const i = f.join(t.path, Q("module", a, String(
|
|
2332
|
+
n.text = "本地模块创建中...";
|
|
2333
|
+
const i = f.join(t.path, Q("module", a, String(s)));
|
|
2327
2334
|
if (j(i))
|
|
2328
2335
|
return U(`${i}已存在,请检查是否对应,本地不再创建。`);
|
|
2329
2336
|
await fe(i, {
|
|
2330
2337
|
recursive: !0
|
|
2331
|
-
}),
|
|
2338
|
+
}), n.succeed(`模块【${i}】创建完成 🎉`);
|
|
2332
2339
|
}
|
|
2333
2340
|
function ui(e) {
|
|
2334
|
-
function t(
|
|
2335
|
-
if (!
|
|
2336
|
-
const
|
|
2337
|
-
|
|
2338
|
-
value:
|
|
2339
|
-
label:
|
|
2340
|
-
type:
|
|
2341
|
+
function t(n) {
|
|
2342
|
+
if (!n.children || n.children.length === 0) return;
|
|
2343
|
+
const s = n.children[0];
|
|
2344
|
+
s && s.label === n.label && s.value === n.value && (!s.children || s.children.length === 0) || n.children.unshift({
|
|
2345
|
+
value: n.value,
|
|
2346
|
+
label: n.label,
|
|
2347
|
+
type: n.type,
|
|
2341
2348
|
children: void 0,
|
|
2342
2349
|
tempTitle: "当前层级"
|
|
2343
2350
|
});
|
|
2344
2351
|
}
|
|
2345
|
-
async function a(
|
|
2346
|
-
const i =
|
|
2352
|
+
async function a(n, s = []) {
|
|
2353
|
+
const i = s.length ? `请选择层级(当前:${s.join(" / ")})` : "请选择层级", o = await E({
|
|
2347
2354
|
message: i,
|
|
2348
|
-
choices:
|
|
2355
|
+
choices: n.map((r) => ({
|
|
2349
2356
|
name: `${r.tempTitle ? r.tempTitle : r.label} ${r.children?.length ? "(有子级)" : ""}`,
|
|
2350
2357
|
value: r
|
|
2351
2358
|
}))
|
|
2352
2359
|
});
|
|
2353
|
-
return o?.children?.length ? (t(o), a(o.children, [...
|
|
2360
|
+
return o?.children?.length ? (t(o), a(o.children, [...s, o.label])) : o;
|
|
2354
2361
|
}
|
|
2355
2362
|
return a(e);
|
|
2356
2363
|
}
|
|
2357
2364
|
async function pi(e, t) {
|
|
2358
|
-
const { type: a, typeStr:
|
|
2365
|
+
const { type: a, typeStr: n } = await Oe("创建", e), { product: s, localProduct: i } = await Me(t.productId), o = await Rt(s.id), r = await ui(o), c = Q("module", r.label, String(r.value)), l = (await ie(s.path, { hasRoot: !0 })).find((h) => h.name === c);
|
|
2359
2366
|
if (!l?.path || !j(l.path))
|
|
2360
2367
|
return m(`本地不存在${c}模块`);
|
|
2361
|
-
let d = await
|
|
2362
|
-
message: `请输入你要创建的${
|
|
2368
|
+
let d = await _({
|
|
2369
|
+
message: `请输入你要创建的${n}名称`,
|
|
2363
2370
|
required: !0,
|
|
2364
2371
|
validate: (h) => h.length > 0 && h.length < 255
|
|
2365
2372
|
});
|
|
2366
2373
|
d = d.trim();
|
|
2367
2374
|
let g = "";
|
|
2368
|
-
if (
|
|
2375
|
+
if (R.MODULE === a && await li(i, l, d), R.CASE === a && (g = await ci(i, l, d)), !t.disableAutoCommit && R.CASE === a) {
|
|
2369
2376
|
const h = y("代码提交中...").start();
|
|
2370
2377
|
try {
|
|
2371
2378
|
await p(`git add . && git commit -m "chore: 创建了用例${f.basename(g)}"`), h.succeed("代码已提交 ✅");
|
|
@@ -2374,24 +2381,24 @@ async function pi(e, t) {
|
|
|
2374
2381
|
}
|
|
2375
2382
|
}
|
|
2376
2383
|
}
|
|
2377
|
-
|
|
2384
|
+
x.command("qa-create").alias("qc").description("创建模块或者用例").argument("[type]", "可选值为module/case").option("--product-id <productId>", "指定产品ID").option("--disable-auto-commit", "是否跳过自动将修改结果提交。").action((...e) => M(pi, ...e));
|
|
2378
2385
|
async function mi(e, t) {
|
|
2379
|
-
const
|
|
2380
|
-
let
|
|
2386
|
+
const n = (await ie(e.path)).filter((r) => r.type === "case");
|
|
2387
|
+
let s;
|
|
2381
2388
|
if (t.length)
|
|
2382
|
-
|
|
2389
|
+
s = n.filter((r) => t.includes(Number(r.id))).map((r) => ({
|
|
2383
2390
|
id: Number(r.id),
|
|
2384
2391
|
path: r.path
|
|
2385
|
-
})),
|
|
2392
|
+
})), s.length || m(`未找到对应用例,请确认输入的用例ID(${t.join(", ")})是否正确`);
|
|
2386
2393
|
else {
|
|
2387
|
-
const r =
|
|
2394
|
+
const r = n.map((c) => ({
|
|
2388
2395
|
value: {
|
|
2389
2396
|
id: Number(c.id),
|
|
2390
2397
|
path: c.path
|
|
2391
2398
|
},
|
|
2392
2399
|
name: c.path.replace(f.resolve(e.path), "")
|
|
2393
2400
|
}));
|
|
2394
|
-
|
|
2401
|
+
s = await V({
|
|
2395
2402
|
message: "选择要删除的用例",
|
|
2396
2403
|
pageSize: 100,
|
|
2397
2404
|
loop: !1,
|
|
@@ -2401,32 +2408,32 @@ async function mi(e, t) {
|
|
|
2401
2408
|
}
|
|
2402
2409
|
});
|
|
2403
2410
|
}
|
|
2404
|
-
const i = y("远程用例删除中...").start(), o =
|
|
2405
|
-
await
|
|
2411
|
+
const i = y("远程用例删除中...").start(), o = s.map((r) => r.id);
|
|
2412
|
+
await fs({
|
|
2406
2413
|
product: Number(e.id),
|
|
2407
2414
|
caseIds: o
|
|
2408
2415
|
}), i.text = "本地用例删除中...";
|
|
2409
|
-
for (const r of
|
|
2416
|
+
for (const r of s)
|
|
2410
2417
|
j(r.path) && N.rm("-rf", r.path);
|
|
2411
2418
|
return i.succeed("用例删除完成"), o;
|
|
2412
2419
|
}
|
|
2413
2420
|
async function di(e, t) {
|
|
2414
|
-
const
|
|
2415
|
-
let
|
|
2421
|
+
const n = (await ie(e.path)).filter((r) => r.type === "module");
|
|
2422
|
+
let s;
|
|
2416
2423
|
if (t.length)
|
|
2417
|
-
|
|
2424
|
+
s = n.filter((r) => t.includes(Number(r.id))).map((r) => ({
|
|
2418
2425
|
id: Number(r.id),
|
|
2419
2426
|
path: r.path
|
|
2420
|
-
})),
|
|
2427
|
+
})), s.length || m(`未找到对应模块,请确认输入的模块ID(${t.join(", ")})是否正确`);
|
|
2421
2428
|
else {
|
|
2422
|
-
const r =
|
|
2429
|
+
const r = n.map((c) => ({
|
|
2423
2430
|
value: {
|
|
2424
2431
|
id: Number(c.id),
|
|
2425
2432
|
path: c.path
|
|
2426
2433
|
},
|
|
2427
2434
|
name: c.path.replace(f.resolve(e.path), "")
|
|
2428
2435
|
}));
|
|
2429
|
-
|
|
2436
|
+
s = await V({
|
|
2430
2437
|
message: "选择要删除的模块",
|
|
2431
2438
|
pageSize: 100,
|
|
2432
2439
|
loop: !1,
|
|
@@ -2436,37 +2443,37 @@ async function di(e, t) {
|
|
|
2436
2443
|
}
|
|
2437
2444
|
});
|
|
2438
2445
|
}
|
|
2439
|
-
|
|
2440
|
-
const i = y("远程模块删除中...").start(), o =
|
|
2441
|
-
await
|
|
2446
|
+
s = s.sort((r, c) => r.path.localeCompare(c.path));
|
|
2447
|
+
const i = y("远程模块删除中...").start(), o = s.map((r) => r.id);
|
|
2448
|
+
await ds({
|
|
2442
2449
|
product: Number(e.id),
|
|
2443
2450
|
moduleIds: o
|
|
2444
2451
|
}), i.text = "本地模块删除中...";
|
|
2445
|
-
for (const r of
|
|
2452
|
+
for (const r of s)
|
|
2446
2453
|
j(r.path) && N.rm("-rf", r.path);
|
|
2447
2454
|
return i.succeed("模块删除完成"), o;
|
|
2448
2455
|
}
|
|
2449
2456
|
async function fi(e, t) {
|
|
2450
|
-
const { type: a, typeStr:
|
|
2457
|
+
const { type: a, typeStr: n } = await Oe("删除", e), { localProduct: s } = await Me(t.productId), i = Xe(t.targetIds);
|
|
2451
2458
|
let o = [];
|
|
2452
|
-
if (
|
|
2459
|
+
if (R.MODULE === a ? o = await di(s, i) : R.CASE === a && (o = await mi(s, i)), !t.disableAutoCommit && await p("git status -s")) {
|
|
2453
2460
|
const r = y("代码提交中...").start();
|
|
2454
2461
|
try {
|
|
2455
|
-
await p(`git add . && git commit -m 'chore: 删除了一些${
|
|
2462
|
+
await p(`git add . && git commit -m 'chore: 删除了一些${n}(${o.join(", ")})'`), r.succeed("代码已提交 ✅");
|
|
2456
2463
|
} catch (c) {
|
|
2457
2464
|
r.fail(`提交失败,${c}`), process.exit(1);
|
|
2458
2465
|
}
|
|
2459
2466
|
}
|
|
2460
2467
|
}
|
|
2461
|
-
|
|
2468
|
+
x.command("qa-remove").alias("qr").description("删除模块或者用例").argument("[type]", "可选值为module/case").option("--product-id <productId>", "指定产品ID").option("--target-ids <targetIds>", "可传指定目标(用例/模块)ID。可传N个,逗号隔开").option("--disable-auto-commit", "是否跳过自动将修改结果提交。").action((...e) => M(fi, ...e));
|
|
2462
2469
|
async function gi(e, t) {
|
|
2463
|
-
const
|
|
2464
|
-
let
|
|
2470
|
+
const n = (await ie(e.path)).filter((g) => g.type === "case");
|
|
2471
|
+
let s;
|
|
2465
2472
|
if (t.targetId) {
|
|
2466
|
-
if (
|
|
2473
|
+
if (s = n.find((g) => Number(g.id) === Number(t.targetId)), !s)
|
|
2467
2474
|
return m(`未找到对应用例,请确认输入的用例ID(${t.targetId})是否正确`);
|
|
2468
2475
|
} else {
|
|
2469
|
-
const g =
|
|
2476
|
+
const g = n.map((h) => ({
|
|
2470
2477
|
value: {
|
|
2471
2478
|
id: Number(h.id),
|
|
2472
2479
|
path: h.path,
|
|
@@ -2474,7 +2481,7 @@ async function gi(e, t) {
|
|
|
2474
2481
|
},
|
|
2475
2482
|
name: h.path.replace(f.resolve(e.path), "")
|
|
2476
2483
|
}));
|
|
2477
|
-
[
|
|
2484
|
+
[s] = await V({
|
|
2478
2485
|
message: "选择要更新的用例",
|
|
2479
2486
|
pageSize: 100,
|
|
2480
2487
|
loop: !1,
|
|
@@ -2485,20 +2492,20 @@ async function gi(e, t) {
|
|
|
2485
2492
|
}
|
|
2486
2493
|
});
|
|
2487
2494
|
}
|
|
2488
|
-
let i = await
|
|
2495
|
+
let i = await _({
|
|
2489
2496
|
message: "修改用例名称",
|
|
2490
|
-
default:
|
|
2497
|
+
default: s.displayName,
|
|
2491
2498
|
required: !0,
|
|
2492
2499
|
validate: (g) => g.length > 0 && g.length < 255,
|
|
2493
2500
|
prefill: "editable"
|
|
2494
2501
|
});
|
|
2495
2502
|
i = i.trim();
|
|
2496
2503
|
const o = y("用例重命名中...").start();
|
|
2497
|
-
i !==
|
|
2498
|
-
id: Number(
|
|
2504
|
+
i !== s.displayName ? (await hs({
|
|
2505
|
+
id: Number(s.id),
|
|
2499
2506
|
name: i
|
|
2500
|
-
}), await je(
|
|
2501
|
-
let r =
|
|
2507
|
+
}), await je(s.path, i, "case", String(s.id)) && o.succeed(`用例重命名成功: ${s.displayName} -> ${i}`), s.displayName = i, s.path = f.join(f.dirname(s.path), Q("case", i, String(s.id)))) : o.succeed("用例名称无变动");
|
|
2508
|
+
let r = C.readJsonSync(f.join(s.path, "config.json")), c;
|
|
2502
2509
|
t.casePriority ? Number.isInteger(t.casePriority) && Number(t.casePriority) > 0 && Number(t.casePriority) < 6 ? c = Number(t.casePriority) : c = await at({
|
|
2503
2510
|
message: "修改用例优先级",
|
|
2504
2511
|
min: 1,
|
|
@@ -2515,44 +2522,44 @@ async function gi(e, t) {
|
|
|
2515
2522
|
validate: (g) => g > 0 && g < 6
|
|
2516
2523
|
});
|
|
2517
2524
|
const u = y("用例优先级设置中...").start();
|
|
2518
|
-
c !== r.priority ? (await
|
|
2519
|
-
id: Number(
|
|
2525
|
+
c !== r.priority ? (await ws({
|
|
2526
|
+
id: Number(s.id),
|
|
2520
2527
|
priority: c
|
|
2521
|
-
}),
|
|
2522
|
-
f.join(
|
|
2528
|
+
}), C.writeJSONSync(
|
|
2529
|
+
f.join(s.path, "config.json"),
|
|
2523
2530
|
{
|
|
2524
2531
|
...r,
|
|
2525
2532
|
priority: c
|
|
2526
2533
|
},
|
|
2527
2534
|
{ spaces: 2 }
|
|
2528
|
-
), u.succeed(`用例优先级修改成功:${r.priority} -> ${c}`)) : u.succeed("用例优先级无变动"), r =
|
|
2535
|
+
), u.succeed(`用例优先级修改成功:${r.priority} -> ${c}`)) : u.succeed("用例优先级无变动"), r = C.readJsonSync(f.join(s.path, "config.json"));
|
|
2529
2536
|
let l;
|
|
2530
|
-
t.casePrecondition ? l = t.casePrecondition : (l = await
|
|
2537
|
+
t.casePrecondition ? l = t.casePrecondition : (l = await _({
|
|
2531
2538
|
message: "修改用例前置条件",
|
|
2532
2539
|
default: r.precondition,
|
|
2533
2540
|
prefill: "editable"
|
|
2534
2541
|
}), l = l.trim());
|
|
2535
2542
|
const d = y("用例前置条件设置中...").start();
|
|
2536
|
-
return l !== r.precondition ? (await
|
|
2537
|
-
id: Number(
|
|
2543
|
+
return l !== r.precondition ? (await ys({
|
|
2544
|
+
id: Number(s.id),
|
|
2538
2545
|
precondition: l
|
|
2539
|
-
}),
|
|
2540
|
-
f.join(
|
|
2546
|
+
}), C.writeJSONSync(
|
|
2547
|
+
f.join(s.path, "config.json"),
|
|
2541
2548
|
{
|
|
2542
2549
|
...r,
|
|
2543
2550
|
precondition: l
|
|
2544
2551
|
},
|
|
2545
2552
|
{ spaces: 2 }
|
|
2546
|
-
), d.succeed(`用例前置条件修改成功:${r.precondition} -> ${l}`)) : d.succeed("用例前置条件无变动"),
|
|
2553
|
+
), d.succeed(`用例前置条件修改成功:${r.precondition} -> ${l}`)) : d.succeed("用例前置条件无变动"), s.id;
|
|
2547
2554
|
}
|
|
2548
2555
|
async function hi(e, t) {
|
|
2549
|
-
const
|
|
2550
|
-
let
|
|
2556
|
+
const n = (await ie(e.path)).filter((r) => r.type === "module");
|
|
2557
|
+
let s;
|
|
2551
2558
|
if (t.targetId) {
|
|
2552
|
-
if (
|
|
2559
|
+
if (s = n.find((r) => Number(r.id) === Number(t.targetId)), !s)
|
|
2553
2560
|
return m(`未找到对应模块,请确认输入的模块ID(${t.targetId})是否正确`);
|
|
2554
2561
|
} else {
|
|
2555
|
-
const r =
|
|
2562
|
+
const r = n.map((c) => ({
|
|
2556
2563
|
value: {
|
|
2557
2564
|
id: Number(c.id),
|
|
2558
2565
|
path: c.path,
|
|
@@ -2560,7 +2567,7 @@ async function hi(e, t) {
|
|
|
2560
2567
|
},
|
|
2561
2568
|
name: c.path.replace(f.resolve(e.path), "")
|
|
2562
2569
|
}));
|
|
2563
|
-
[
|
|
2570
|
+
[s] = await V({
|
|
2564
2571
|
message: "选择要更新的模块",
|
|
2565
2572
|
pageSize: 100,
|
|
2566
2573
|
loop: !1,
|
|
@@ -2571,60 +2578,60 @@ async function hi(e, t) {
|
|
|
2571
2578
|
}
|
|
2572
2579
|
});
|
|
2573
2580
|
}
|
|
2574
|
-
let i = await
|
|
2581
|
+
let i = await _({
|
|
2575
2582
|
message: "修改模块名称",
|
|
2576
|
-
default:
|
|
2583
|
+
default: s.displayName,
|
|
2577
2584
|
required: !0,
|
|
2578
2585
|
validate: (r) => r.length > 0 && r.length < 255,
|
|
2579
2586
|
prefill: "editable"
|
|
2580
2587
|
});
|
|
2581
2588
|
i = i.trim();
|
|
2582
2589
|
const o = y("模块重命名中...").start();
|
|
2583
|
-
return i !==
|
|
2584
|
-
id: Number(
|
|
2590
|
+
return i !== s.displayName ? (await gs({
|
|
2591
|
+
id: Number(s.id),
|
|
2585
2592
|
name: i
|
|
2586
|
-
}), await je(
|
|
2593
|
+
}), await je(s.path, i, "module", String(s.id)) && o.succeed(`模块重命名成功: ${s.displayName} -> ${i}`)) : o.succeed("模块名称无变动"), s.id;
|
|
2587
2594
|
}
|
|
2588
2595
|
async function wi(e, t) {
|
|
2589
|
-
const { type: a, typeStr:
|
|
2596
|
+
const { type: a, typeStr: n } = await Oe("修改", e), { localProduct: s } = await Me(t.productId);
|
|
2590
2597
|
let i;
|
|
2591
|
-
if (
|
|
2598
|
+
if (R.MODULE === a ? i = await hi(s, t) : R.CASE === a && (i = await gi(s, t)), !t.disableAutoCommit && await p("git status -s")) {
|
|
2592
2599
|
const o = y("代码提交中...").start();
|
|
2593
2600
|
try {
|
|
2594
|
-
await p(`git add . && git commit -m 'chore: 修改了一个${
|
|
2601
|
+
await p(`git add . && git commit -m 'chore: 修改了一个${n}(${i})'`), o.succeed("代码已提交 ✅");
|
|
2595
2602
|
} catch (r) {
|
|
2596
2603
|
o.fail(`提交失败,${r}`), process.exit(1);
|
|
2597
2604
|
}
|
|
2598
2605
|
}
|
|
2599
2606
|
}
|
|
2600
|
-
|
|
2607
|
+
x.command("qa-update").alias("qu").description("修改模块或者用例").argument("[type]", "可选值为module/case").option("--product-id <productId>", "指定产品ID").option("--target-id <targetId>", "可传指定目标(用例/模块)ID").option("--target-name <targetName>", "可传指定目标(用例/模块)修改后的名称").option("--case-priority <casePriority>", "如果是用例,指定修改后的优先级").option("--case-precondition <casePrecondition>", "如果是用例,指定修改后的前置条件").option("--disable-auto-commit", "是否跳过自动将修改结果提交。").action((...e) => M(wi, ...e));
|
|
2601
2608
|
async function yi(e, t) {
|
|
2602
2609
|
if (!e.length)
|
|
2603
2610
|
return [];
|
|
2604
|
-
const a = ha(20),
|
|
2605
|
-
(
|
|
2611
|
+
const a = ha(20), n = e.map(
|
|
2612
|
+
(s) => a(async () => {
|
|
2606
2613
|
try {
|
|
2607
|
-
const i = t.env || "production", o = await p(`python ${
|
|
2614
|
+
const i = t.env || "production", o = await p(`python ${s.path}/main.py --env ${i}`);
|
|
2608
2615
|
try {
|
|
2609
|
-
|
|
2616
|
+
s.result = JSON.parse(o);
|
|
2610
2617
|
} catch {
|
|
2611
|
-
m(`用例${
|
|
2618
|
+
m(`用例${s.displayName}[${s.id}]返回格式错误:${o}`);
|
|
2612
2619
|
}
|
|
2613
2620
|
} catch (i) {
|
|
2614
2621
|
const o = i instanceof Error ? i.message : String(i);
|
|
2615
|
-
m(`用例${
|
|
2622
|
+
m(`用例${s.displayName}[${s.id}]执行失败: ${o}`);
|
|
2616
2623
|
}
|
|
2617
2624
|
})
|
|
2618
2625
|
);
|
|
2619
|
-
return await Promise.all(
|
|
2626
|
+
return await Promise.all(n), e;
|
|
2620
2627
|
}
|
|
2621
2628
|
async function $i(e) {
|
|
2622
2629
|
ee(), H();
|
|
2623
2630
|
const { localProduct: t } = await Me(e.productId);
|
|
2624
|
-
let a
|
|
2625
|
-
const
|
|
2631
|
+
let a;
|
|
2632
|
+
const s = (await ie(t.path)).filter((c) => c.type === "case");
|
|
2626
2633
|
if (e.all)
|
|
2627
|
-
a =
|
|
2634
|
+
a = s.map((c) => ({
|
|
2628
2635
|
id: Number(c.id),
|
|
2629
2636
|
path: c.path,
|
|
2630
2637
|
displayName: c.displayName
|
|
@@ -2632,13 +2639,13 @@ async function $i(e) {
|
|
|
2632
2639
|
else {
|
|
2633
2640
|
const c = Xe(e.caseIds);
|
|
2634
2641
|
if (c.length)
|
|
2635
|
-
a =
|
|
2642
|
+
a = s.filter((u) => c.includes(Number(u.id))).map((u) => ({
|
|
2636
2643
|
id: Number(u.id),
|
|
2637
2644
|
path: u.path,
|
|
2638
2645
|
displayName: u.displayName
|
|
2639
2646
|
}));
|
|
2640
2647
|
else {
|
|
2641
|
-
const u =
|
|
2648
|
+
const u = s.map((l) => ({
|
|
2642
2649
|
value: {
|
|
2643
2650
|
id: Number(l.id),
|
|
2644
2651
|
path: l.path,
|
|
@@ -2665,31 +2672,31 @@ async function $i(e) {
|
|
|
2665
2672
|
return U("执行报告如下:"), console.log(JSON.stringify(r, null, 2)), process.exit(0);
|
|
2666
2673
|
const c = r.reduce((d, g) => d + g.result.length, 0);
|
|
2667
2674
|
i.warn(`【${r.length}】个用例执行出错,【${c}】个BUG将创建。`);
|
|
2668
|
-
let u
|
|
2675
|
+
let u;
|
|
2669
2676
|
if (e.executionId)
|
|
2670
2677
|
Number.isNaN(Number(e.executionId)) && m(`executionId ${e.executionId}不是正整数`), u = Number(e.executionId);
|
|
2671
2678
|
else {
|
|
2672
|
-
const d = await
|
|
2679
|
+
const d = await vs(), g = await E({
|
|
2673
2680
|
message: "请选择用例执行出错后,BUG所属的项目",
|
|
2674
|
-
choices: d.map(({ id: v, name:
|
|
2675
|
-
}), h = await
|
|
2681
|
+
choices: d.map(({ id: v, name: G }) => ({ name: G, value: v }))
|
|
2682
|
+
}), h = await As(g);
|
|
2676
2683
|
u = await E({
|
|
2677
2684
|
message: "请选择用例执行出错后,BUG所属的执行",
|
|
2678
|
-
choices: h.map(({ id: v, name:
|
|
2685
|
+
choices: h.map(({ id: v, name: G }) => ({ name: G, value: v }))
|
|
2679
2686
|
});
|
|
2680
2687
|
}
|
|
2681
2688
|
let l;
|
|
2682
2689
|
if (e.buildId)
|
|
2683
2690
|
l = e.buildId;
|
|
2684
2691
|
else {
|
|
2685
|
-
const d = await
|
|
2692
|
+
const d = await bs(Number(u));
|
|
2686
2693
|
if (d.length) {
|
|
2687
2694
|
const g = await Re({
|
|
2688
2695
|
message: "请选择BUG关联的构建版本(可多选;非必选,默认主干)",
|
|
2689
2696
|
required: !1,
|
|
2690
|
-
choices: d.map(({ id: h, name: v, date:
|
|
2697
|
+
choices: d.map(({ id: h, name: v, date: G, builder: P }) => ({
|
|
2691
2698
|
value: h,
|
|
2692
|
-
name: `${v} ${
|
|
2699
|
+
name: `${v} ${P} ${G}`
|
|
2693
2700
|
}))
|
|
2694
2701
|
});
|
|
2695
2702
|
g.length ? l = g.join(",") : l = "";
|
|
@@ -2698,7 +2705,7 @@ async function $i(e) {
|
|
|
2698
2705
|
}
|
|
2699
2706
|
i.start("上传中...");
|
|
2700
2707
|
for (const d of r)
|
|
2701
|
-
await
|
|
2708
|
+
await $s({
|
|
2702
2709
|
caseId: d.id,
|
|
2703
2710
|
caseResult: "fail",
|
|
2704
2711
|
stepResults: d.result,
|
|
@@ -2711,46 +2718,46 @@ async function $i(e) {
|
|
|
2711
2718
|
);
|
|
2712
2719
|
}
|
|
2713
2720
|
}
|
|
2714
|
-
|
|
2721
|
+
x.command("qa-exec").alias("qe").description("执行用例").option("--product-id <productId>", "指定产品ID").option("--case-ids <caseIds>", "可传指定用例ID。可传N个,逗号隔开").option("--all", "执行产品下所有用例").option("--concurrency <concurrency>", "最多并行执行脚本数。默认20").option("--process-step <step>", "不传默认2。 1. 仅在本地返回执行报告; 2. 执行出错的结果提交到禅道用例并提交BUG。").option("--env <env>", "环境变量,会作为参数传递给执行脚本。默认production").option("--execution-id <executionId>", "提bug时,要关联的禅道执行ID").option("--build-id <buildId>", "提bug时,要关联的禅道执行构建ID。默认主干(trunk)").action((...e) => M($i, ...e));
|
|
2715
2722
|
const vi = async () => {
|
|
2716
|
-
const { projects: e } = await
|
|
2723
|
+
const { projects: e } = await Os(), t = W();
|
|
2717
2724
|
if (t.serverProjectURL) {
|
|
2718
|
-
const
|
|
2719
|
-
(
|
|
2725
|
+
const n = e.find(
|
|
2726
|
+
(s) => Pe(s.url, t.serverProjectURL)
|
|
2720
2727
|
);
|
|
2721
|
-
if (
|
|
2728
|
+
if (n)
|
|
2722
2729
|
return {
|
|
2723
|
-
projectId: decodeURIComponent(
|
|
2724
|
-
moduleList:
|
|
2730
|
+
projectId: decodeURIComponent(se(t.serverProjectURL)),
|
|
2731
|
+
moduleList: n.modules || []
|
|
2725
2732
|
};
|
|
2726
2733
|
}
|
|
2727
2734
|
const a = await E({
|
|
2728
2735
|
message: "请选择本项目对应的服务端项目",
|
|
2729
|
-
choices: e.map((
|
|
2730
|
-
name: `${
|
|
2731
|
-
value:
|
|
2736
|
+
choices: e.map((n) => ({
|
|
2737
|
+
name: `${n.name}(${n.url})`,
|
|
2738
|
+
value: n.url
|
|
2732
2739
|
}))
|
|
2733
2740
|
});
|
|
2734
2741
|
return It({ ...t, serverProjectURL: a }), {
|
|
2735
|
-
projectId: decodeURIComponent(
|
|
2736
|
-
moduleList: e.find((
|
|
2742
|
+
projectId: decodeURIComponent(se(a)),
|
|
2743
|
+
moduleList: e.find((n) => n.url === a)?.modules || []
|
|
2737
2744
|
};
|
|
2738
2745
|
}, Ai = async (e, t) => {
|
|
2739
|
-
const a = t ? t.split(",").filter((
|
|
2746
|
+
const a = t ? t.split(",").filter((s) => e.map((i) => i.name).includes(s.trim())) : [];
|
|
2740
2747
|
if (a.length)
|
|
2741
2748
|
return a;
|
|
2742
|
-
const
|
|
2749
|
+
const n = await Re({
|
|
2743
2750
|
message: "请选择对应的后端服务,不选默认全部",
|
|
2744
|
-
choices: e.map((
|
|
2745
|
-
name: `${
|
|
2746
|
-
value:
|
|
2751
|
+
choices: e.map((s) => ({
|
|
2752
|
+
name: `${s.name}(${s.desc})`,
|
|
2753
|
+
value: s.name
|
|
2747
2754
|
})),
|
|
2748
2755
|
required: !1,
|
|
2749
2756
|
pageSize: 10,
|
|
2750
2757
|
loop: !0
|
|
2751
2758
|
});
|
|
2752
|
-
return
|
|
2753
|
-
}, pt = [
|
|
2759
|
+
return n?.length ? n : e.map((s) => s.name);
|
|
2760
|
+
}, pt = [D.DEV, D.TEST], bi = async (e) => e && pt.includes(e.trim()) ? e : await E({
|
|
2754
2761
|
message: "请选择对应的环境",
|
|
2755
2762
|
choices: At.filter((t) => pt.includes(t.value))
|
|
2756
2763
|
}), Qe = (e) => {
|
|
@@ -2758,12 +2765,12 @@ const vi = async () => {
|
|
|
2758
2765
|
return e.match(t)?.[1];
|
|
2759
2766
|
}, Si = async (e, t) => {
|
|
2760
2767
|
try {
|
|
2761
|
-
const a = await
|
|
2768
|
+
const a = await ne({
|
|
2762
2769
|
url: e,
|
|
2763
2770
|
method: "get"
|
|
2764
|
-
}),
|
|
2765
|
-
return
|
|
2766
|
-
Object.entries(a.paths).map(([
|
|
2771
|
+
}), n = Qe(e);
|
|
2772
|
+
return n && (a.paths = Object.fromEntries(
|
|
2773
|
+
Object.entries(a.paths).map(([s, i]) => [`/${n}${s}`, i])
|
|
2767
2774
|
)), wa(a, {
|
|
2768
2775
|
throwOnValidateError: !t
|
|
2769
2776
|
});
|
|
@@ -2772,36 +2779,36 @@ const vi = async () => {
|
|
|
2772
2779
|
}
|
|
2773
2780
|
}, Ni = (e) => {
|
|
2774
2781
|
const t = (a) => {
|
|
2775
|
-
const { reason:
|
|
2776
|
-
return `## ${Qe(
|
|
2777
|
-
${
|
|
2782
|
+
const { reason: n, url: s } = a;
|
|
2783
|
+
return `## ${Qe(s)}服务接口文档校验失败
|
|
2784
|
+
${n.message}`;
|
|
2778
2785
|
};
|
|
2779
2786
|
return `# 服务端接口文档校验失败
|
|
2780
2787
|
${e.map(t).join(`
|
|
2781
2788
|
`)}`;
|
|
2782
2789
|
}, ji = async (e, t) => {
|
|
2783
|
-
const a = Ni(e),
|
|
2784
|
-
(c) => c.projects.some((u) => Pe(u,
|
|
2790
|
+
const a = Ni(e), n = W(), { groups: s } = await Ct(), i = s.find(
|
|
2791
|
+
(c) => c.projects.some((u) => Pe(u, n.serverProjectURL))
|
|
2785
2792
|
);
|
|
2786
2793
|
t.fail("API数据解析失败"), i || (t.fail("未找到对应的项目群聊组!"), process.stdout.write(`${A.red(a)}
|
|
2787
2794
|
`), process.exit(1));
|
|
2788
|
-
const { code: o, message: r } = await
|
|
2795
|
+
const { code: o, message: r } = await Ss({
|
|
2789
2796
|
content: a,
|
|
2790
2797
|
webhooks: [i.url]
|
|
2791
2798
|
});
|
|
2792
2799
|
o !== 0 && t.fail(`发送消息到企微群组失败: ${A.red(r)}`), process.stdout.write(`${A.red(a)}
|
|
2793
2800
|
`), process.exit(1);
|
|
2794
2801
|
}, Ti = async (e) => {
|
|
2795
|
-
const { moduleList: t, services: a, env:
|
|
2802
|
+
const { moduleList: t, services: a, env: n, skipSwaggerValidate: s } = e, i = t.filter((l) => a.includes(l.name)).map((l) => l.swagger);
|
|
2796
2803
|
if (!i.length)
|
|
2797
2804
|
throw new Error("Failed to fetch Swagger JSON");
|
|
2798
2805
|
const o = i.flatMap((l) => {
|
|
2799
|
-
const d = l.find((g) => g.env ===
|
|
2806
|
+
const d = l.find((g) => g.env === n);
|
|
2800
2807
|
return d ? [d.url] : [];
|
|
2801
2808
|
});
|
|
2802
2809
|
if (!o.length)
|
|
2803
2810
|
throw new Error("Failed to fetch Swagger JSON");
|
|
2804
|
-
const r = y("API数据请求中...").start(), c = await Promise.allSettled(o.map((l) => Si(l,
|
|
2811
|
+
const r = y("API数据请求中...").start(), c = await Promise.allSettled(o.map((l) => Si(l, s))), u = c.flatMap(
|
|
2805
2812
|
(l, d) => l.status === "rejected" ? [{ reason: l.reason, url: o[d] }] : []
|
|
2806
2813
|
);
|
|
2807
2814
|
return u.length && await ji(u, r), r.succeed("API数据请求成功"), c.flatMap((l, d) => l.status === "fulfilled" ? [{ serverName: Qe(o[d]), swaggerJson: l.value }] : []);
|
|
@@ -2821,16 +2828,16 @@ ${e.map(t).join(`
|
|
|
2821
2828
|
message: e,
|
|
2822
2829
|
options: t,
|
|
2823
2830
|
emptyValidateMsg: a,
|
|
2824
|
-
pageSize:
|
|
2825
|
-
multiple:
|
|
2831
|
+
pageSize: n = 20,
|
|
2832
|
+
multiple: s = !0,
|
|
2826
2833
|
formatShowToValue: i
|
|
2827
2834
|
}) => {
|
|
2828
2835
|
const o = i ? typeof i == "function" ? i : (r) => r.map((c) => String(c.value)).join(", ") : void 0;
|
|
2829
2836
|
return V({
|
|
2830
2837
|
message: e,
|
|
2831
|
-
pageSize:
|
|
2838
|
+
pageSize: n,
|
|
2832
2839
|
clearInputWhenSelected: !0,
|
|
2833
|
-
multiple:
|
|
2840
|
+
multiple: s,
|
|
2834
2841
|
loop: !0,
|
|
2835
2842
|
options: (r) => r ? t.filter((c) => (c.name ?? c.label ?? c.value).includes(r)) : t,
|
|
2836
2843
|
validate: a ? (r) => r.length ? !0 : a : void 0,
|
|
@@ -2856,7 +2863,7 @@ ${e.map(t).join(`
|
|
|
2856
2863
|
const t = mt(e);
|
|
2857
2864
|
return t !== !0 && m(t), e;
|
|
2858
2865
|
}
|
|
2859
|
-
return
|
|
2866
|
+
return _({
|
|
2860
2867
|
message: "请输入 API 输出目录,默认为 src/services",
|
|
2861
2868
|
default: "src/services",
|
|
2862
2869
|
validate: mt
|
|
@@ -2871,13 +2878,13 @@ class qt {
|
|
|
2871
2878
|
this.o = y("API 开始生成...").start(), a === "single" ? await this.startGenerateSingleApi() : await this.startGenerateAllApi(), this.o.succeed("API 生成成功");
|
|
2872
2879
|
}
|
|
2873
2880
|
async startGenerateSingleApi() {
|
|
2874
|
-
const t = [], a = this.options.remoteSwaggerJsons.map((
|
|
2881
|
+
const t = [], a = this.options.remoteSwaggerJsons.map((n) => n.swaggerJson);
|
|
2875
2882
|
this.o.text = "获取 API 列表...";
|
|
2876
|
-
for (const
|
|
2877
|
-
const { apis:
|
|
2883
|
+
for (const n of a) {
|
|
2884
|
+
const { apis: s } = await ya(n, {
|
|
2878
2885
|
throwOnValidateError: !this.options.skipSwaggerValidate
|
|
2879
2886
|
});
|
|
2880
|
-
t.push(...
|
|
2887
|
+
t.push(...s.map((i) => ({ name: `${i.path}${i.summary ? `(${i.summary})` : ""}`, value: i.path })));
|
|
2881
2888
|
}
|
|
2882
2889
|
this.o.stop();
|
|
2883
2890
|
try {
|
|
@@ -2889,22 +2896,22 @@ class qt {
|
|
|
2889
2896
|
formatShowToValue: !0
|
|
2890
2897
|
})
|
|
2891
2898
|
);
|
|
2892
|
-
} catch (
|
|
2893
|
-
this.o.fail(`API 生成失败: ${
|
|
2899
|
+
} catch (n) {
|
|
2900
|
+
this.o.fail(`API 生成失败: ${n.message}`);
|
|
2894
2901
|
}
|
|
2895
2902
|
}
|
|
2896
2903
|
async startGenerateAllApi() {
|
|
2897
2904
|
const t = await this.generateAllApi();
|
|
2898
2905
|
this.o.stop();
|
|
2899
|
-
const a = await Ei(this.options.dir),
|
|
2900
|
-
ta(
|
|
2901
|
-
const
|
|
2906
|
+
const a = await Ei(this.options.dir), n = pe(a);
|
|
2907
|
+
ta(n, { recursive: !0 });
|
|
2908
|
+
const s = [];
|
|
2902
2909
|
this.o.start(), this.o.text = "API 生成中...";
|
|
2903
2910
|
for (const i of t) {
|
|
2904
|
-
const { path: o, content: r } = i, c = pe(
|
|
2905
|
-
|
|
2911
|
+
const { path: o, content: r } = i, c = pe(n, o);
|
|
2912
|
+
s.push(c), ve(c, r);
|
|
2906
2913
|
}
|
|
2907
|
-
this.o.text = "开始格式化代码", await this.formatApiContent(
|
|
2914
|
+
this.o.text = "开始格式化代码", await this.formatApiContent(s), this.o.text = "代码格式化完成", this.o.succeed(`API 已生成到 ${a} 目录下`);
|
|
2908
2915
|
}
|
|
2909
2916
|
}
|
|
2910
2917
|
class Ii extends qt {
|
|
@@ -2921,14 +2928,14 @@ class Ii extends qt {
|
|
|
2921
2928
|
);
|
|
2922
2929
|
}
|
|
2923
2930
|
async generateSingleApi(t) {
|
|
2924
|
-
const { remoteSwaggerJsons: a, skipSwaggerValidate:
|
|
2925
|
-
for (const { swaggerJson:
|
|
2931
|
+
const { remoteSwaggerJsons: a, skipSwaggerValidate: n } = this.options;
|
|
2932
|
+
for (const { swaggerJson: s, serverName: i } of a) {
|
|
2926
2933
|
if (!t.some((r) => r.startsWith(`/${i}`)))
|
|
2927
2934
|
continue;
|
|
2928
2935
|
const o = await va({
|
|
2929
|
-
swaggerJson:
|
|
2936
|
+
swaggerJson: s,
|
|
2930
2937
|
controller: t,
|
|
2931
|
-
throwOnValidateError: !
|
|
2938
|
+
throwOnValidateError: !n,
|
|
2932
2939
|
showHeaderComment: !1
|
|
2933
2940
|
});
|
|
2934
2941
|
console.log(ht(o, { language: "typescript", ignoreIllegals: !0 }));
|
|
@@ -2943,11 +2950,11 @@ class Ci extends qt {
|
|
|
2943
2950
|
try {
|
|
2944
2951
|
const a = await Ri.lintFiles(t);
|
|
2945
2952
|
await wt.outputFixes(a);
|
|
2946
|
-
for (const
|
|
2947
|
-
const
|
|
2948
|
-
filepath:
|
|
2953
|
+
for (const n of t) {
|
|
2954
|
+
const s = pe(n), i = dt(s, "utf-8"), o = await Sa.format(i, {
|
|
2955
|
+
filepath: s
|
|
2949
2956
|
});
|
|
2950
|
-
ve(
|
|
2957
|
+
ve(s, o);
|
|
2951
2958
|
}
|
|
2952
2959
|
} catch (a) {
|
|
2953
2960
|
console.error(a), this.o.stop(), m("API 格式化失败,请检查是否配置 eslint 和 prettier");
|
|
@@ -2963,15 +2970,15 @@ class Ci extends qt {
|
|
|
2963
2970
|
);
|
|
2964
2971
|
}
|
|
2965
2972
|
async generateSingleApi(t) {
|
|
2966
|
-
const { remoteSwaggerJsons: a, skipSwaggerValidate:
|
|
2967
|
-
for (const { swaggerJson:
|
|
2973
|
+
const { remoteSwaggerJsons: a, skipSwaggerValidate: n } = this.options;
|
|
2974
|
+
for (const { swaggerJson: s, serverName: i } of a) {
|
|
2968
2975
|
if (!t.some((r) => r.startsWith(`/${i}`)))
|
|
2969
2976
|
continue;
|
|
2970
2977
|
const o = await ba({
|
|
2971
|
-
swaggerJson:
|
|
2978
|
+
swaggerJson: s,
|
|
2972
2979
|
merge: !0,
|
|
2973
2980
|
controller: t,
|
|
2974
|
-
throwOnValidateError: !
|
|
2981
|
+
throwOnValidateError: !n,
|
|
2975
2982
|
importMethods: !1
|
|
2976
2983
|
});
|
|
2977
2984
|
console.log(ht(o, { language: "typescript", ignoreIllegals: !0 }));
|
|
@@ -2991,11 +2998,11 @@ const Li = (e) => {
|
|
|
2991
2998
|
};
|
|
2992
2999
|
async function Pi(e) {
|
|
2993
3000
|
ee(), H();
|
|
2994
|
-
const { moduleList: t } = await vi(), { services: a, env:
|
|
3001
|
+
const { moduleList: t } = await vi(), { services: a, env: n, skipSwaggerValidate: s = !1 } = e, i = await Ai(t, a), o = Ze(), r = await bi(n), c = await Ti({
|
|
2995
3002
|
moduleList: t,
|
|
2996
3003
|
services: i,
|
|
2997
3004
|
env: r,
|
|
2998
|
-
skipSwaggerValidate:
|
|
3005
|
+
skipSwaggerValidate: s
|
|
2999
3006
|
}), u = await ki();
|
|
3000
3007
|
await xi({
|
|
3001
3008
|
remoteSwaggerJsons: c,
|
|
@@ -3004,7 +3011,7 @@ async function Pi(e) {
|
|
|
3004
3011
|
apiType: o
|
|
3005
3012
|
}), process.exit(0);
|
|
3006
3013
|
}
|
|
3007
|
-
|
|
3014
|
+
x.command("api").alias("a").description("选择对应的服务端项目,获取接口并转成ts接口代码及类型").option("--services [services]", "指定需要生成的服务。多个使用逗号隔开").option("--env [env]", "指定环境。dev/test/release").option("--dir [dir]", "输出的目录。默认为 src/services").option("--skip-swagger-validate", "是否跳过 swagger 校验").action((...e) => M(Pi, ...e));
|
|
3008
3015
|
const Di = 10, Oi = async () => {
|
|
3009
3016
|
const e = await p("git branch --show-current"), t = [
|
|
3010
3017
|
w.MASTER,
|
|
@@ -3016,18 +3023,18 @@ const Di = 10, Oi = async () => {
|
|
|
3016
3023
|
`remotes/origin/${w.MASTER}`
|
|
3017
3024
|
];
|
|
3018
3025
|
return (await p("git branch -a")).trim().split(`
|
|
3019
|
-
`).map((
|
|
3020
|
-
name:
|
|
3021
|
-
value:
|
|
3026
|
+
`).map((n) => n.trim()).filter((n) => n && !n.includes("HEAD")).filter((n) => !t.includes(n)).filter((n, s, i) => i.indexOf(n) === s).map((n) => ({
|
|
3027
|
+
name: n,
|
|
3028
|
+
value: n
|
|
3022
3029
|
}));
|
|
3023
3030
|
}, Mi = async (e) => (await p(
|
|
3024
3031
|
`git log ${e} -n ${Di} --format="%H%x1f%s%x1f%an%x1f%ae%x1f%aI" --no-merges`
|
|
3025
3032
|
)).trim().split(`
|
|
3026
3033
|
`).filter((a) => a.trim() !== "").map((a) => {
|
|
3027
|
-
const [
|
|
3034
|
+
const [n = "", s = "", i = "", o = "", r = ""] = a.split("");
|
|
3028
3035
|
return {
|
|
3029
|
-
hash:
|
|
3030
|
-
message:
|
|
3036
|
+
hash: n,
|
|
3037
|
+
message: s,
|
|
3031
3038
|
authorName: i,
|
|
3032
3039
|
authorEmail: o,
|
|
3033
3040
|
authorDate: r
|
|
@@ -3050,7 +3057,7 @@ const Di = 10, Oi = async () => {
|
|
|
3050
3057
|
return [];
|
|
3051
3058
|
}
|
|
3052
3059
|
}, Fi = async (e, t) => {
|
|
3053
|
-
const a = aa(pe(ua(), "z-pick-commit-")),
|
|
3060
|
+
const a = aa(pe(ua(), "z-pick-commit-")), n = pe(a, `${e.hash}.patch`), s = pe(a, `${e.hash}.message`);
|
|
3054
3061
|
try {
|
|
3055
3062
|
ye(t, `正在生成 patch: ${e.hash.slice(0, 8)} ${e.message}`);
|
|
3056
3063
|
const i = we(`git format-patch -1 ${e.hash} --stdout --binary --full-index`, {
|
|
@@ -3061,7 +3068,7 @@ const Di = 10, Oi = async () => {
|
|
|
3061
3068
|
status: "failed",
|
|
3062
3069
|
message: he(i.stderr) || `生成 patch 失败: ${e.hash}`
|
|
3063
3070
|
};
|
|
3064
|
-
if (ve(
|
|
3071
|
+
if (ve(n, he(i.stdout)), ve(s, await Bi(e.hash)), ye(t, `正在检查 patch 是否已存在: ${e.hash.slice(0, 8)} ${e.message}`), we(`git apply --reverse --check "${n}"`, {
|
|
3065
3072
|
silent: !0
|
|
3066
3073
|
}).code === 0)
|
|
3067
3074
|
return {
|
|
@@ -3069,7 +3076,7 @@ const Di = 10, Oi = async () => {
|
|
|
3069
3076
|
reason: `已跳过重复 patch: ${e.hash.slice(0, 8)} ${e.message}`
|
|
3070
3077
|
};
|
|
3071
3078
|
ye(t, `正在应用 patch: ${e.hash.slice(0, 8)} ${e.message}`);
|
|
3072
|
-
const r = we(`git apply --3way --whitespace=nowarn "${
|
|
3079
|
+
const r = we(`git apply --3way --whitespace=nowarn "${n}"`, {
|
|
3073
3080
|
silent: !0
|
|
3074
3081
|
});
|
|
3075
3082
|
if (r.code !== 0) {
|
|
@@ -3093,7 +3100,7 @@ const Di = 10, Oi = async () => {
|
|
|
3093
3100
|
message: he(c.stderr) || `暂存 patch 失败: ${e.hash}`
|
|
3094
3101
|
};
|
|
3095
3102
|
N.env.GIT_AUTHOR_NAME = e.authorName, N.env.GIT_AUTHOR_EMAIL = e.authorEmail, N.env.GIT_AUTHOR_DATE = e.authorDate, ye(t, `正在提交 commit: ${e.hash.slice(0, 8)} ${e.message}`);
|
|
3096
|
-
const u = we(`git commit --file "${
|
|
3103
|
+
const u = we(`git commit --file "${s}"`, {
|
|
3097
3104
|
silent: !0
|
|
3098
3105
|
});
|
|
3099
3106
|
return u.code !== 0 ? {
|
|
@@ -3103,14 +3110,14 @@ const Di = 10, Oi = async () => {
|
|
|
3103
3110
|
status: "success"
|
|
3104
3111
|
};
|
|
3105
3112
|
} finally {
|
|
3106
|
-
delete N.env.GIT_AUTHOR_NAME, delete N.env.GIT_AUTHOR_EMAIL, delete N.env.GIT_AUTHOR_DATE,
|
|
3113
|
+
delete N.env.GIT_AUTHOR_NAME, delete N.env.GIT_AUTHOR_EMAIL, delete N.env.GIT_AUTHOR_DATE, sa(a, {
|
|
3107
3114
|
force: !0,
|
|
3108
3115
|
recursive: !0
|
|
3109
3116
|
});
|
|
3110
3117
|
}
|
|
3111
|
-
}, Zt = (e) => e.slice(0, 8), Gi = (e) => e.replace("T", " ").slice(0, 16), Ji = (e) => `${Gi(e.authorDate)} ${e.authorName} ${Zt(e.hash)} ${e.message}`, Ui = (e, t) => t.map((a) => e.find((
|
|
3112
|
-
const
|
|
3113
|
-
return e.indexOf(
|
|
3118
|
+
}, Zt = (e) => e.slice(0, 8), Gi = (e) => e.replace("T", " ").slice(0, 16), Ji = (e) => `${Gi(e.authorDate)} ${e.authorName} ${Zt(e.hash)} ${e.message}`, Ui = (e, t) => t.map((a) => e.find((n) => n.hash === a)).filter((a) => !!a).sort((a, n) => {
|
|
3119
|
+
const s = e.indexOf(a);
|
|
3120
|
+
return e.indexOf(n) - s;
|
|
3114
3121
|
});
|
|
3115
3122
|
async function Vi() {
|
|
3116
3123
|
ee(), H(), await ge();
|
|
@@ -3126,21 +3133,21 @@ async function Vi() {
|
|
|
3126
3133
|
});
|
|
3127
3134
|
if (!a)
|
|
3128
3135
|
return;
|
|
3129
|
-
const
|
|
3136
|
+
const n = await Mi(a), s = n.map((r) => ({
|
|
3130
3137
|
name: Ji(r),
|
|
3131
3138
|
value: r.hash
|
|
3132
3139
|
})), i = await Je({
|
|
3133
3140
|
message: "选择需要pick的commit。选中的 commit 会按照提交时间顺序执行。",
|
|
3134
|
-
options:
|
|
3141
|
+
options: s,
|
|
3135
3142
|
emptyValidateMsg: "至少选择一个commit",
|
|
3136
3143
|
formatShowToValue: (r) => r.map((c) => {
|
|
3137
|
-
const u =
|
|
3144
|
+
const u = n.find((l) => l.hash === c.value);
|
|
3138
3145
|
return u ? Zt(u.hash) : String(c.value);
|
|
3139
3146
|
}).join(", ")
|
|
3140
3147
|
});
|
|
3141
3148
|
if (!i?.length)
|
|
3142
3149
|
return;
|
|
3143
|
-
const o = Ui(
|
|
3150
|
+
const o = Ui(n, i);
|
|
3144
3151
|
e.start(`开始处理分支 ${a} 的 commit...`);
|
|
3145
3152
|
for (const r of o) {
|
|
3146
3153
|
const c = await Fi(r, e);
|
|
@@ -3151,7 +3158,7 @@ async function Vi() {
|
|
|
3151
3158
|
else if (c.status === "conflict") {
|
|
3152
3159
|
e.fail(`处理失败: ${r.hash.slice(0, 8)} ${r.message}`), J("检测到 patch 冲突,已停止后续 commit 处理。"), J(`冲突提交: ${r.hash.slice(0, 8)} ${r.message}`), c.conflictFiles.length && J(`冲突文件:
|
|
3153
3160
|
${c.conflictFiles.join(`
|
|
3154
|
-
`)}`), J("请先手动解决冲突并处理当前工作区,再重新执行 pick-commit。"), await
|
|
3161
|
+
`)}`), J("请先手动解决冲突并处理当前工作区,再重新执行 pick-commit。"), await z(Se(), r.message, "utf-8");
|
|
3155
3162
|
return;
|
|
3156
3163
|
} else {
|
|
3157
3164
|
e.fail(`处理失败: ${r.hash.slice(0, 8)} ${r.message}`), J(c.message);
|
|
@@ -3161,7 +3168,7 @@ ${c.conflictFiles.join(`
|
|
|
3161
3168
|
}
|
|
3162
3169
|
e.succeed(`分支 ${a} 处理完成`), e.succeed("pick commit 完成");
|
|
3163
3170
|
}
|
|
3164
|
-
|
|
3171
|
+
x.command("pick").alias("p").description("从其他分支选择并应用 Commit内容 到当前分支").action((...e) => M(Vi, ...e));
|
|
3165
3172
|
function Wi() {
|
|
3166
3173
|
process.on("unhandledRejection", (e) => {
|
|
3167
3174
|
}), process.on("uncaughtException", (e) => {
|
|
@@ -3172,17 +3179,17 @@ async function Hi() {
|
|
|
3172
3179
|
if (Date.now() - Number(e) > Number(t) * 24 * 3600 * 1e3) {
|
|
3173
3180
|
const a = await He();
|
|
3174
3181
|
De(a);
|
|
3175
|
-
let
|
|
3182
|
+
let n;
|
|
3176
3183
|
try {
|
|
3177
|
-
const
|
|
3178
|
-
setTimeout(() => o(
|
|
3184
|
+
const s = "TIME_OUT", i = new Promise((o) => {
|
|
3185
|
+
setTimeout(() => o(s), 3e3);
|
|
3179
3186
|
});
|
|
3180
|
-
|
|
3187
|
+
n = await Promise.race([
|
|
3181
3188
|
i,
|
|
3182
3189
|
p(`npm view ${ce.name} version --registry https://registry.npmmirror.com/`)
|
|
3183
|
-
]),
|
|
3184
|
-
} catch (
|
|
3185
|
-
console.log("升级出错!请重试,或者手动升级"), m(
|
|
3190
|
+
]), n !== s && n !== ce.version && (console.log(`${A.blue(ce.name)}本地版本为${ce.version},低于线上版本${n},开始升级`), await Ft(n)), de("latestCheckVersionTimestamp", Date.now()), X();
|
|
3191
|
+
} catch (s) {
|
|
3192
|
+
console.log("升级出错!请重试,或者手动升级"), m(s);
|
|
3186
3193
|
}
|
|
3187
3194
|
}
|
|
3188
3195
|
}
|
|
@@ -3190,7 +3197,7 @@ async function qi() {
|
|
|
3190
3197
|
const e = Na(process.argv.slice(2));
|
|
3191
3198
|
if (!(e.h || e.help || e.v || e.version) && !(["init", "i"].includes(e._[0]) && ![".", "prepare"].includes(e._[1])))
|
|
3192
3199
|
if (jt()) {
|
|
3193
|
-
const t =
|
|
3200
|
+
const t = C.readJSONSync(xe());
|
|
3194
3201
|
k(t.profile), de(t.main), De(t.constants), await Hi();
|
|
3195
3202
|
} else
|
|
3196
3203
|
m(`请先初始化z-develop(执行 z i)。更多见${bt}`);
|
|
@@ -3198,5 +3205,5 @@ async function qi() {
|
|
|
3198
3205
|
async function Zi() {
|
|
3199
3206
|
Wi(), await qi();
|
|
3200
3207
|
}
|
|
3201
|
-
|
|
3202
|
-
|
|
3208
|
+
x.name("z-develop").alias("z").description(`z-develop, 开发流程管理工具。了解更多: ${A.blue(bt)}`).usage("<command> [options]").hook("preAction", Zi).version(ce.version, "-v, --version", "当前版本号").helpOption("-h, --help", "帮助").showHelpAfterError("可以使用z -h查看帮助。");
|
|
3209
|
+
x.parse();
|