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