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