@done-coding/cli-git 0.5.5-alpha.1 → 0.6.0
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/es/cli.mjs +5 -6
- package/es/helpers.mjs +9 -9
- package/es/index-8bd8ff1f.js +19 -0
- package/es/index-964abda4.js +603 -0
- package/es/index.mjs +17 -10
- package/package.json +4 -4
- package/types/config/index.d.ts +3 -0
- package/types/handlers/check.d.ts +51 -0
- package/types/handlers/clone.d.ts +8 -0
- package/types/handlers/hooks.d.ts +7 -0
- package/types/handlers/index.d.ts +9 -0
- package/types/handlers/init.d.ts +19 -0
- package/types/index.d.ts +2 -2
- package/types/injectInfo.json.d.ts +1 -1
- package/types/types/check.d.ts +40 -0
- package/types/{utils/types.d.ts → types/clone.d.ts} +0 -10
- package/types/types/hooks.d.ts +5 -0
- package/types/types/index.d.ts +5 -0
- package/types/types/init.d.ts +10 -0
- package/types/types/subcommand.d.ts +13 -0
- package/types/utils/check.d.ts +20 -0
- package/types/utils/config.d.ts +1 -1
- package/types/utils/get-repo.d.ts +1 -1
- package/types/utils/hooks.d.ts +7 -0
- package/types/utils/index.d.ts +2 -3
- package/types/utils/path.d.ts +2 -0
- package/types/utils/question.d.ts +1 -1
- package/es/clone-11819b7f.js +0 -222
- package/es/index-49e07bde.js +0 -60
- package/types/handler.d.ts +0 -5
- package/types/utils/clone.d.ts +0 -7
- package/types/utils/init.d.ts +0 -9
package/es/cli.mjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { c as m } from "./index-
|
|
2
|
+
import { c as m } from "./index-8bd8ff1f.js";
|
|
3
|
+
import "./index-964abda4.js";
|
|
3
4
|
import "@done-coding/cli-utils";
|
|
4
|
-
import "
|
|
5
|
-
import "@done-coding/request-axios";
|
|
6
|
-
import "axios";
|
|
5
|
+
import "node:child_process";
|
|
7
6
|
import "node:fs";
|
|
8
7
|
import "node:path";
|
|
9
|
-
import "
|
|
10
|
-
import "
|
|
8
|
+
import "@done-coding/request-axios";
|
|
9
|
+
import "axios";
|
|
11
10
|
m();
|
package/es/helpers.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import "
|
|
5
|
-
import "axios";
|
|
2
|
+
import { g as s, G as n, a, h as m } from "./index-964abda4.js";
|
|
3
|
+
import { xPrompts as e } from "@done-coding/cli-utils";
|
|
4
|
+
import "node:child_process";
|
|
6
5
|
import "node:fs";
|
|
7
6
|
import "node:path";
|
|
8
|
-
import "
|
|
7
|
+
import "@done-coding/request-axios";
|
|
8
|
+
import "axios";
|
|
9
9
|
const u = async (r) => {
|
|
10
10
|
console.log("克隆done-coding系列项目"), console.log("选择平台:");
|
|
11
|
-
const { platform: o } = await
|
|
11
|
+
const { platform: o } = await e(s(n.GITEE));
|
|
12
12
|
console.log("选择用户名:");
|
|
13
|
-
const { username:
|
|
13
|
+
const { username: t } = await e(
|
|
14
14
|
a(
|
|
15
15
|
{
|
|
16
16
|
[n.GITHUB]: "done-coding",
|
|
@@ -18,9 +18,9 @@ const u = async (r) => {
|
|
|
18
18
|
}[o]
|
|
19
19
|
)
|
|
20
20
|
);
|
|
21
|
-
console.log("platform:", o), console.log("username:",
|
|
21
|
+
console.log("platform:", o), console.log("username:", t), await m({
|
|
22
22
|
platform: o,
|
|
23
|
-
username:
|
|
23
|
+
username: t,
|
|
24
24
|
projectName: r
|
|
25
25
|
});
|
|
26
26
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { c as a, i as t } from "./index-964abda4.js";
|
|
3
|
+
import { createMainCommand as r, createSubcommand as s } from "@done-coding/cli-utils";
|
|
4
|
+
const {
|
|
5
|
+
cliConfig: { moduleName: o }
|
|
6
|
+
} = t, c = (n = !1) => {
|
|
7
|
+
const e = n ? o : void 0, m = `$0${n ? ` ${o}` : ""} <command> [options]`;
|
|
8
|
+
return { command: e, usage: m };
|
|
9
|
+
}, u = async () => r({
|
|
10
|
+
...a,
|
|
11
|
+
...c()
|
|
12
|
+
}), f = () => s({
|
|
13
|
+
...a,
|
|
14
|
+
...c(!0)
|
|
15
|
+
});
|
|
16
|
+
export {
|
|
17
|
+
f as a,
|
|
18
|
+
u as c
|
|
19
|
+
};
|
|
@@ -0,0 +1,603 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { lookForParentTarget as Y, log as i, decryptAES as Z, encryptAES as W, xPrompts as h, HooksNameEnum as m, addHuskyHooks as ee, initHandlerCommon as te, getConfigFileCommonOptions as I, readConfigFile as R, getCurrentBranchName as se, getCommitByHookName as oe, resolveMergeInfoByGitReflogAction as re, checkCurrentIsRebasing as ne, resolveMergeInfoByCommitMsg as ce, getCurrentBranchLastCommitList as ae, getLastReflogList as ie, createSubcommand as ge } from "@done-coding/cli-utils";
|
|
3
|
+
import { execSync as B } from "node:child_process";
|
|
4
|
+
import _ from "node:fs";
|
|
5
|
+
import b from "node:path";
|
|
6
|
+
import { createRequest as N } from "@done-coding/request-axios";
|
|
7
|
+
import fe from "axios";
|
|
8
|
+
var p = /* @__PURE__ */ ((e) => (e.INIT = "init", e.CLONE = "clone", e.HOOKS = "hooks", e.CHECK = "check", e))(p || {}), d = /* @__PURE__ */ ((e) => (e.DEFAULT = "default", e.CLONE_CONFIG = "cloneConfig", e))(d || {}), E = /* @__PURE__ */ ((e) => (e.GITHUB = "github", e.GITEE = "gitee", e))(E || {}), C = /* @__PURE__ */ ((e) => (e.REVERSE_MERGE = "reverseMerge", e))(C || {}), u = /* @__PURE__ */ ((e) => (e.REFLOG_ACTION = "reflog-action", e.COMMIT_MSG = "commit-msg", e.COMMIT_RECORD = "commit-record", e.PRE_REBASE = "pre-rebase", e))(u || {});
|
|
9
|
+
const me = 3e4, w = Math.random(), L = {
|
|
10
|
+
timeout: me,
|
|
11
|
+
getBusinessCode() {
|
|
12
|
+
return w;
|
|
13
|
+
},
|
|
14
|
+
getBusinessMsg(e) {
|
|
15
|
+
return e.statusText;
|
|
16
|
+
},
|
|
17
|
+
getBusinessData(e) {
|
|
18
|
+
return e.data;
|
|
19
|
+
},
|
|
20
|
+
businessSuccessCodeList: [w],
|
|
21
|
+
axios: fe
|
|
22
|
+
}, U = N({
|
|
23
|
+
basePath: " https://gitee.com",
|
|
24
|
+
...L
|
|
25
|
+
}), x = N({
|
|
26
|
+
basePath: "https://api.github.com",
|
|
27
|
+
...L
|
|
28
|
+
}), le = ({
|
|
29
|
+
username: e
|
|
30
|
+
}) => U({
|
|
31
|
+
url: `/api/v5/users/${e}/repos`,
|
|
32
|
+
method: "GET"
|
|
33
|
+
}), pe = ({
|
|
34
|
+
accessToken: e
|
|
35
|
+
}) => U({
|
|
36
|
+
url: "/api/v5/user/repos",
|
|
37
|
+
method: "GET",
|
|
38
|
+
params: {
|
|
39
|
+
access_token: e,
|
|
40
|
+
per_page: 100,
|
|
41
|
+
page: 1,
|
|
42
|
+
sort: "updated"
|
|
43
|
+
}
|
|
44
|
+
}), ue = ({
|
|
45
|
+
username: e
|
|
46
|
+
}) => x({
|
|
47
|
+
url: `/users/${e}/repos`,
|
|
48
|
+
method: "GET"
|
|
49
|
+
}), Ee = ({
|
|
50
|
+
accessToken: e
|
|
51
|
+
}) => x({
|
|
52
|
+
url: "/user/repos",
|
|
53
|
+
method: "GET",
|
|
54
|
+
headers: {
|
|
55
|
+
Authorization: `Bearer ${e}`
|
|
56
|
+
},
|
|
57
|
+
params: {
|
|
58
|
+
per_page: 100,
|
|
59
|
+
page: 1,
|
|
60
|
+
sort: "updated"
|
|
61
|
+
}
|
|
62
|
+
}), A = {
|
|
63
|
+
name: "@done-coding/cli-git",
|
|
64
|
+
version: "0.6.0",
|
|
65
|
+
description: "git跨平台操作命令行工具",
|
|
66
|
+
cliConfig: {
|
|
67
|
+
namespaceDir: ".done-coding",
|
|
68
|
+
moduleName: "git"
|
|
69
|
+
}
|
|
70
|
+
}, {
|
|
71
|
+
cliConfig: { namespaceDir: he, moduleName: de }
|
|
72
|
+
} = A, F = `./${he}/${de}`, T = `${F}.json`, H = (e) => `${F}/.${e}`, D = ({ platform: e, username: t }) => `${e}/${t}`, Re = (e) => {
|
|
73
|
+
const { platform: t } = e, s = H(t), r = Y(s, {
|
|
74
|
+
isFindFarthest: !1
|
|
75
|
+
});
|
|
76
|
+
if (!r) {
|
|
77
|
+
i.warn("配置文件不存在");
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const o = `${r}/${s}`, c = _.readFileSync(o, "utf-8"), n = D(e), g = Z({ encryptedText: c, secretKey: n });
|
|
81
|
+
if (!g) {
|
|
82
|
+
i.warn("配置文件解密失败");
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
return JSON.parse(g);
|
|
86
|
+
}, Me = ({
|
|
87
|
+
rootDir: e,
|
|
88
|
+
username: t,
|
|
89
|
+
platform: s,
|
|
90
|
+
accessToken: r
|
|
91
|
+
}) => {
|
|
92
|
+
const o = H(s), n = JSON.stringify({
|
|
93
|
+
accessToken: r
|
|
94
|
+
}), g = D({ platform: s, username: t }), l = W({ text: n, secretKey: g }), a = b.join(e, o);
|
|
95
|
+
_.mkdirSync(b.dirname(a), {
|
|
96
|
+
recursive: !0
|
|
97
|
+
}), _.writeFileSync(a, l, "utf-8"), i.success(`配置信息保存成功 ${a}`);
|
|
98
|
+
}, y = [
|
|
99
|
+
{ title: "GitHub", value: E.GITHUB },
|
|
100
|
+
{ title: "Gitee", value: E.GITEE }
|
|
101
|
+
], v = (e) => {
|
|
102
|
+
let t = 0;
|
|
103
|
+
if (e) {
|
|
104
|
+
const s = y.findIndex(
|
|
105
|
+
(r) => r.value === e
|
|
106
|
+
);
|
|
107
|
+
s >= 0 && (t = s);
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
type: "select",
|
|
111
|
+
name: "platform",
|
|
112
|
+
message: "选择git平台",
|
|
113
|
+
choices: y,
|
|
114
|
+
initial: t
|
|
115
|
+
};
|
|
116
|
+
}, K = (e) => ({
|
|
117
|
+
type: "text",
|
|
118
|
+
name: "username",
|
|
119
|
+
message: "请输入用户名",
|
|
120
|
+
format: (t) => t.trim(),
|
|
121
|
+
validate: (t) => t.length > 0 || "用户名不能为空",
|
|
122
|
+
initial: e
|
|
123
|
+
}), Ce = {
|
|
124
|
+
type: "password",
|
|
125
|
+
name: "accessToken",
|
|
126
|
+
message: "请输入git access token",
|
|
127
|
+
format: (e) => e.trim(),
|
|
128
|
+
validate: (e) => e.length > 0 || "access token不能为空"
|
|
129
|
+
}, $e = async ({
|
|
130
|
+
platform: e,
|
|
131
|
+
username: t
|
|
132
|
+
} = {}) => {
|
|
133
|
+
const s = {
|
|
134
|
+
platform: e,
|
|
135
|
+
username: t
|
|
136
|
+
};
|
|
137
|
+
e || (s.platform = (await h(v())).platform), t || (s.username = (await h(K())).username);
|
|
138
|
+
const { platform: r, username: o } = s;
|
|
139
|
+
let c = [];
|
|
140
|
+
const n = Re({
|
|
141
|
+
username: o,
|
|
142
|
+
platform: r
|
|
143
|
+
});
|
|
144
|
+
let g = n == null ? void 0 : n.accessToken;
|
|
145
|
+
i.stage(`正在获取${o}的${r}仓库列表...`);
|
|
146
|
+
const l = {
|
|
147
|
+
username: o,
|
|
148
|
+
accessToken: g
|
|
149
|
+
};
|
|
150
|
+
switch (s.platform) {
|
|
151
|
+
case E.GITHUB: {
|
|
152
|
+
c = (await (l.accessToken ? Ee : ue)(l)).data.map((f) => ({
|
|
153
|
+
name: f.name,
|
|
154
|
+
httpUrl: f.clone_url,
|
|
155
|
+
sshUrl: f.ssh_url,
|
|
156
|
+
description: f.description || ""
|
|
157
|
+
}));
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
case E.GITEE: {
|
|
161
|
+
c = (await (l.accessToken ? pe : le)(l)).data.map((f) => ({
|
|
162
|
+
name: f.name,
|
|
163
|
+
httpUrl: f.html_url,
|
|
164
|
+
sshUrl: f.ssh_url,
|
|
165
|
+
description: f.description || ""
|
|
166
|
+
}));
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
default:
|
|
170
|
+
return i.error(`未知平台${r}`), process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
if (i.success(`获取${o}的${r}仓库列表成功`), c.length === 0) {
|
|
173
|
+
i.warn(`${o} 可获取${r}仓库列表为空`);
|
|
174
|
+
return;
|
|
175
|
+
} else
|
|
176
|
+
i.stage(`共${c.length}个仓库`);
|
|
177
|
+
const { repoUrl: a } = await h({
|
|
178
|
+
name: "repoUrl",
|
|
179
|
+
type: "select",
|
|
180
|
+
message: "选择仓库",
|
|
181
|
+
choices: c.map((f) => ({
|
|
182
|
+
title: `${f.name} ${f.description}`,
|
|
183
|
+
value: f.sshUrl
|
|
184
|
+
}))
|
|
185
|
+
});
|
|
186
|
+
return a;
|
|
187
|
+
}, Oe = [
|
|
188
|
+
m.PRE_COMMIT,
|
|
189
|
+
m.PRE_MERGE_COMMIT,
|
|
190
|
+
m.PREPARE_COMMIT_MSG,
|
|
191
|
+
m.COMMIT_MSG,
|
|
192
|
+
m.PRE_REBASE,
|
|
193
|
+
m.POST_COMMIT,
|
|
194
|
+
m.POST_MERGE,
|
|
195
|
+
m.PRE_PUSH
|
|
196
|
+
], _e = [
|
|
197
|
+
m.PRE_MERGE_COMMIT,
|
|
198
|
+
m.PREPARE_COMMIT_MSG,
|
|
199
|
+
m.POST_MERGE,
|
|
200
|
+
m.PRE_PUSH,
|
|
201
|
+
m.PRE_REBASE
|
|
202
|
+
], $ = (e) => {
|
|
203
|
+
const {
|
|
204
|
+
[p.CHECK]: { [C.REVERSE_MERGE]: t }
|
|
205
|
+
} = e;
|
|
206
|
+
return t;
|
|
207
|
+
}, Ie = (e) => Math.max(
|
|
208
|
+
0,
|
|
209
|
+
...Object.values(e).map(({ logCount: t }) => t)
|
|
210
|
+
), Te = (e, t) => Object.entries(e).reduce(
|
|
211
|
+
(s, [r, { afterHash: o, logCount: c }]) => {
|
|
212
|
+
let n = c - 1;
|
|
213
|
+
if (o) {
|
|
214
|
+
const g = t.findIndex((l) => l.hash === o);
|
|
215
|
+
g !== -1 && (i.info(
|
|
216
|
+
`${r} 设置 只检测 ${o} 之后的日志 即 下标 [0 - ${g})`
|
|
217
|
+
), n = Math.min(n, g - 1));
|
|
218
|
+
}
|
|
219
|
+
return i.info(`${r} 最多检查${n + 1}条`), s[r] = n, s;
|
|
220
|
+
},
|
|
221
|
+
{}
|
|
222
|
+
), G = ({
|
|
223
|
+
mergeInfo: e,
|
|
224
|
+
configMap: t,
|
|
225
|
+
currentBranch: s
|
|
226
|
+
}) => {
|
|
227
|
+
if (!e)
|
|
228
|
+
return;
|
|
229
|
+
const { fromBranch: r, toBranch: o = s } = e;
|
|
230
|
+
if (r === s) {
|
|
231
|
+
i.skip(`跳过: 允许远程${r} => 本地${o}`);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const n = !!Object.keys(t).map(
|
|
235
|
+
(g) => new RegExp(g)
|
|
236
|
+
).find(
|
|
237
|
+
(g) => g.test(r)
|
|
238
|
+
);
|
|
239
|
+
return n || i.skip(`跳过: 允许${r} => ${o}`), n;
|
|
240
|
+
}, Ge = {
|
|
241
|
+
[p.CHECK]: {
|
|
242
|
+
[C.REVERSE_MERGE]: {
|
|
243
|
+
[/^test$/.source]: {
|
|
244
|
+
includeRebase: !0,
|
|
245
|
+
logCount: 10,
|
|
246
|
+
afterHash: ""
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}, Pe = () => ({
|
|
251
|
+
...I({
|
|
252
|
+
configPathDefault: T
|
|
253
|
+
}),
|
|
254
|
+
type: {
|
|
255
|
+
alias: "t",
|
|
256
|
+
describe: "初始化类型",
|
|
257
|
+
choices: [d.DEFAULT, d.CLONE_CONFIG],
|
|
258
|
+
default: d.DEFAULT
|
|
259
|
+
}
|
|
260
|
+
}), Se = (e) => {
|
|
261
|
+
B(`npm pkg set scripts.postprepare="${e} init"`);
|
|
262
|
+
}, j = async (e) => {
|
|
263
|
+
const { type: t } = e;
|
|
264
|
+
switch (t) {
|
|
265
|
+
case d.DEFAULT: {
|
|
266
|
+
const { rootDir: s, isSubCommand: r, _: o } = e, c = `${e.$0}${r ? ` ${o[0]}` : ""}`;
|
|
267
|
+
return await ee({
|
|
268
|
+
hookNames: _e,
|
|
269
|
+
rootDir: s,
|
|
270
|
+
getCode: (n) => `npx ${c} hooks ${n} "$@"`
|
|
271
|
+
}), await Se(c), te(Ge, e, {
|
|
272
|
+
onFileGenerated: (n) => {
|
|
273
|
+
i.info(`文件生成成功: ${n}`);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
case d.CLONE_CONFIG: {
|
|
278
|
+
const { rootDir: s } = e, { platform: r } = await h(v()), { username: o } = await h(K()), { accessToken: c } = await h(Ce);
|
|
279
|
+
return Me({
|
|
280
|
+
rootDir: s,
|
|
281
|
+
platform: r,
|
|
282
|
+
username: o,
|
|
283
|
+
accessToken: c
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
default:
|
|
287
|
+
throw new Error(`未知的初始化类型: ${t}`);
|
|
288
|
+
}
|
|
289
|
+
}, ke = {
|
|
290
|
+
command: p.INIT,
|
|
291
|
+
describe: "初始化配置文件",
|
|
292
|
+
options: Pe(),
|
|
293
|
+
handler: j
|
|
294
|
+
}, be = () => ({
|
|
295
|
+
projectName: {
|
|
296
|
+
type: "string",
|
|
297
|
+
alias: "p",
|
|
298
|
+
describe: "项目名称"
|
|
299
|
+
}
|
|
300
|
+
}), we = () => ({
|
|
301
|
+
platform: {
|
|
302
|
+
describe: "选择git平台",
|
|
303
|
+
type: "string",
|
|
304
|
+
choices: [E.GITHUB, E.GITEE]
|
|
305
|
+
},
|
|
306
|
+
username: {
|
|
307
|
+
describe: "git平台用户名",
|
|
308
|
+
type: "string"
|
|
309
|
+
}
|
|
310
|
+
}), V = async (e) => {
|
|
311
|
+
const t = await $e(e), { projectName: s } = e;
|
|
312
|
+
B(
|
|
313
|
+
`git clone ${t} ${s ? `${s} ` : ""}--depth=1`,
|
|
314
|
+
{ stdio: "inherit" }
|
|
315
|
+
), i.success(`克隆${t}成功`);
|
|
316
|
+
}, ye = {
|
|
317
|
+
command: `${p.CLONE} <platform> <username>`,
|
|
318
|
+
describe: "从选择的git平台克隆代码",
|
|
319
|
+
options: be(),
|
|
320
|
+
positionals: we(),
|
|
321
|
+
handler: V
|
|
322
|
+
}, Be = () => I({
|
|
323
|
+
configPathDefault: T
|
|
324
|
+
}), Ne = () => ({
|
|
325
|
+
type: {
|
|
326
|
+
describe: "检测类型",
|
|
327
|
+
type: "string",
|
|
328
|
+
choices: [C.REVERSE_MERGE]
|
|
329
|
+
}
|
|
330
|
+
}), Le = ({
|
|
331
|
+
config: e,
|
|
332
|
+
currentBranch: t
|
|
333
|
+
}) => {
|
|
334
|
+
const s = re();
|
|
335
|
+
if (!s)
|
|
336
|
+
return;
|
|
337
|
+
const r = $(e), o = G({
|
|
338
|
+
mergeInfo: s,
|
|
339
|
+
configMap: r,
|
|
340
|
+
currentBranch: t
|
|
341
|
+
}), { fromBranch: c } = s;
|
|
342
|
+
if (o) {
|
|
343
|
+
const n = `发现当前执行 git ${process.env.GIT_REFLOG_ACTION}
|
|
344
|
+
意欲反向合并${c}
|
|
345
|
+
拦截 !!!
|
|
346
|
+
|
|
347
|
+
--------- 建议 ---------
|
|
348
|
+
可以通过
|
|
349
|
+
1.查看当前已提交记录的最新版本号
|
|
350
|
+
git log
|
|
351
|
+
2. 回退到当前已提交记录的最新版本
|
|
352
|
+
git reset --hard <当前已提交记录的最新版本号>
|
|
353
|
+
`;
|
|
354
|
+
return i.error(n), process.exit(1);
|
|
355
|
+
}
|
|
356
|
+
}, Ue = ({
|
|
357
|
+
config: e,
|
|
358
|
+
currentBranch: t,
|
|
359
|
+
commitMsg: s,
|
|
360
|
+
rootDir: r
|
|
361
|
+
}) => {
|
|
362
|
+
if (ne(r))
|
|
363
|
+
return i.skip("当前在变基中, 不通过提交信息检测合并");
|
|
364
|
+
const o = ce(s), c = $(e);
|
|
365
|
+
if (G({
|
|
366
|
+
mergeInfo: o,
|
|
367
|
+
configMap: c,
|
|
368
|
+
currentBranch: t
|
|
369
|
+
})) {
|
|
370
|
+
const { fromBranch: g, toBranch: l = t } = o, a = `禁止${g}被合并: ${g} => ${l}
|
|
371
|
+
|
|
372
|
+
--------- 建议 ---------
|
|
373
|
+
可以通过
|
|
374
|
+
1.查看当前已提交记录的最新版本号
|
|
375
|
+
git log
|
|
376
|
+
2. 回退到当前已提交记录的最新版本
|
|
377
|
+
git reset --hard <当前已提交记录的最新版本号>
|
|
378
|
+
`;
|
|
379
|
+
return i.error(a), process.exit(1);
|
|
380
|
+
}
|
|
381
|
+
}, xe = ({
|
|
382
|
+
config: e,
|
|
383
|
+
currentBranch: t
|
|
384
|
+
}) => {
|
|
385
|
+
const s = $(e), r = Ie(s);
|
|
386
|
+
if (!r)
|
|
387
|
+
return;
|
|
388
|
+
const o = ae({ count: r }), c = Te(s, o), n = o.map((a) => a.hash), l = ie({
|
|
389
|
+
/** 考虑reflog存在往复切换 */
|
|
390
|
+
count: r + 30,
|
|
391
|
+
filterItem: (a) => n.includes(a.hash)
|
|
392
|
+
}).reduce(
|
|
393
|
+
(a, f) => (f.mergeInfo && (a[f.hash] = f), a),
|
|
394
|
+
{}
|
|
395
|
+
);
|
|
396
|
+
o.forEach((a, f) => {
|
|
397
|
+
var P;
|
|
398
|
+
const O = a.mergeInfo || ((P = l[a.hash]) == null ? void 0 : P.mergeInfo);
|
|
399
|
+
O && Object.entries(s).forEach(([S]) => {
|
|
400
|
+
const k = c[S];
|
|
401
|
+
if (f > k) {
|
|
402
|
+
i.skip(`${S} 只检测${k + 1}条, 超出不再检测`);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
const z = G({
|
|
406
|
+
mergeInfo: O,
|
|
407
|
+
configMap: s,
|
|
408
|
+
currentBranch: t
|
|
409
|
+
}), { fromBranch: Q } = O;
|
|
410
|
+
if (z) {
|
|
411
|
+
const X = `发现${Q}被合并
|
|
412
|
+
本次提交版本 ${a.hash}
|
|
413
|
+
提交注释 ${a.message}
|
|
414
|
+
提交人: ${a.committer}
|
|
415
|
+
提交时间: ${a.commitTime}
|
|
416
|
+
|
|
417
|
+
--------- 建议 ---------
|
|
418
|
+
可以通过
|
|
419
|
+
1.查看操作日志版本号为${a.hash}的前一次操作的版本号
|
|
420
|
+
git reflog
|
|
421
|
+
3. 回退到前一次操作的版本号
|
|
422
|
+
git reset --hard <当前已提交记录的最新版本号>
|
|
423
|
+
`;
|
|
424
|
+
return i.error(X), process.exit(1);
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
});
|
|
428
|
+
}, Ae = ({
|
|
429
|
+
config: e,
|
|
430
|
+
rebaseInfo: t
|
|
431
|
+
}) => {
|
|
432
|
+
const s = $(e), r = Object.entries(s), { targetBranch: o, originBranch: c } = t;
|
|
433
|
+
for (let [n, g] of r)
|
|
434
|
+
if (g.includeRebase) {
|
|
435
|
+
if (new RegExp(n).test(o)) {
|
|
436
|
+
const a = `禁止变基到${o}的基线
|
|
437
|
+
即 禁止${c}分子包含${o}分支(可能)存在的其他需求的代码`;
|
|
438
|
+
return i.error(a), process.exit(1);
|
|
439
|
+
}
|
|
440
|
+
} else
|
|
441
|
+
i.skip(`不检测是否变基到${o}的基线`);
|
|
442
|
+
i.success(`允许变基到${o}`);
|
|
443
|
+
}, M = async (e) => {
|
|
444
|
+
const { config: t, way: s } = e, r = se();
|
|
445
|
+
switch (s) {
|
|
446
|
+
case u.REFLOG_ACTION: {
|
|
447
|
+
Le({ config: t, currentBranch: r });
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
case u.COMMIT_MSG: {
|
|
451
|
+
const { hookName: o, rootDir: c } = e, n = oe({
|
|
452
|
+
hookName: o,
|
|
453
|
+
rootDir: c
|
|
454
|
+
});
|
|
455
|
+
Ue({
|
|
456
|
+
config: t,
|
|
457
|
+
currentBranch: r,
|
|
458
|
+
commitMsg: n,
|
|
459
|
+
rootDir: c
|
|
460
|
+
});
|
|
461
|
+
break;
|
|
462
|
+
}
|
|
463
|
+
case u.COMMIT_RECORD: {
|
|
464
|
+
xe({ config: t, currentBranch: r });
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
case u.PRE_REBASE: {
|
|
468
|
+
const { args: o } = e, [
|
|
469
|
+
c,
|
|
470
|
+
/** 能进入 rebase 说明originBranch有值 或者 当前在某个分支上 */
|
|
471
|
+
n = r
|
|
472
|
+
] = o;
|
|
473
|
+
Ae({
|
|
474
|
+
config: t,
|
|
475
|
+
rebaseInfo: {
|
|
476
|
+
targetBranch: c,
|
|
477
|
+
originBranch: n
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
default:
|
|
483
|
+
throw new Error(`不支持的检测方式${s}`);
|
|
484
|
+
}
|
|
485
|
+
}, q = async (e) => {
|
|
486
|
+
const t = await R(e), { type: s } = e;
|
|
487
|
+
switch (s) {
|
|
488
|
+
case C.REVERSE_MERGE: {
|
|
489
|
+
await M({
|
|
490
|
+
rootDir: e.rootDir,
|
|
491
|
+
config: t,
|
|
492
|
+
way: u.COMMIT_RECORD
|
|
493
|
+
});
|
|
494
|
+
break;
|
|
495
|
+
}
|
|
496
|
+
default:
|
|
497
|
+
throw new Error(`不支持的检测类型${s}`);
|
|
498
|
+
}
|
|
499
|
+
}, Fe = {
|
|
500
|
+
command: `${p.CHECK} <type>`,
|
|
501
|
+
describe: "检查git操作",
|
|
502
|
+
options: Be(),
|
|
503
|
+
positionals: Ne(),
|
|
504
|
+
handler: q
|
|
505
|
+
}, He = () => I({
|
|
506
|
+
configPathDefault: T
|
|
507
|
+
}), De = () => ({
|
|
508
|
+
name: {
|
|
509
|
+
describe: "钩子名称",
|
|
510
|
+
type: "string",
|
|
511
|
+
choices: Oe
|
|
512
|
+
}
|
|
513
|
+
}), J = async (e) => {
|
|
514
|
+
const { name: t, rootDir: s, args: r } = e;
|
|
515
|
+
switch (t) {
|
|
516
|
+
case m.PRE_MERGE_COMMIT: {
|
|
517
|
+
const o = await R(e);
|
|
518
|
+
M({
|
|
519
|
+
config: o,
|
|
520
|
+
way: u.REFLOG_ACTION,
|
|
521
|
+
rootDir: s
|
|
522
|
+
});
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
525
|
+
case m.PREPARE_COMMIT_MSG: {
|
|
526
|
+
const o = await R(e);
|
|
527
|
+
M({
|
|
528
|
+
config: o,
|
|
529
|
+
way: u.COMMIT_MSG,
|
|
530
|
+
hookName: t,
|
|
531
|
+
rootDir: s
|
|
532
|
+
});
|
|
533
|
+
break;
|
|
534
|
+
}
|
|
535
|
+
case m.POST_MERGE:
|
|
536
|
+
case m.PRE_PUSH: {
|
|
537
|
+
const o = await R(e);
|
|
538
|
+
M({
|
|
539
|
+
config: o,
|
|
540
|
+
way: u.COMMIT_RECORD,
|
|
541
|
+
rootDir: s
|
|
542
|
+
});
|
|
543
|
+
break;
|
|
544
|
+
}
|
|
545
|
+
case m.PRE_REBASE: {
|
|
546
|
+
const o = await R(e);
|
|
547
|
+
M({
|
|
548
|
+
config: o,
|
|
549
|
+
way: u.PRE_REBASE,
|
|
550
|
+
args: r
|
|
551
|
+
});
|
|
552
|
+
break;
|
|
553
|
+
}
|
|
554
|
+
default:
|
|
555
|
+
i.error(`${t} 当前未支持处理`);
|
|
556
|
+
}
|
|
557
|
+
}, ve = {
|
|
558
|
+
command: `${p.HOOKS} <name> [args...]`,
|
|
559
|
+
describe: "git钩子回调",
|
|
560
|
+
options: He(),
|
|
561
|
+
positionals: De(),
|
|
562
|
+
handler: J
|
|
563
|
+
}, Ye = async (e, t) => {
|
|
564
|
+
switch (e) {
|
|
565
|
+
case p.INIT:
|
|
566
|
+
return j(t);
|
|
567
|
+
case p.CLONE:
|
|
568
|
+
return V(t);
|
|
569
|
+
case p.HOOKS:
|
|
570
|
+
return J(t);
|
|
571
|
+
case p.CHECK:
|
|
572
|
+
return q(t);
|
|
573
|
+
default:
|
|
574
|
+
throw new Error(`不支持的命令 ${e}`);
|
|
575
|
+
}
|
|
576
|
+
}, { version: Ke, description: je } = A, Ze = {
|
|
577
|
+
describe: je,
|
|
578
|
+
version: Ke,
|
|
579
|
+
subcommands: [
|
|
580
|
+
ke,
|
|
581
|
+
ye,
|
|
582
|
+
ve,
|
|
583
|
+
Fe
|
|
584
|
+
].map(ge),
|
|
585
|
+
demandCommandCount: 1
|
|
586
|
+
};
|
|
587
|
+
export {
|
|
588
|
+
E as G,
|
|
589
|
+
K as a,
|
|
590
|
+
$e as b,
|
|
591
|
+
Ze as c,
|
|
592
|
+
j as d,
|
|
593
|
+
ke as e,
|
|
594
|
+
ye as f,
|
|
595
|
+
v as g,
|
|
596
|
+
V as h,
|
|
597
|
+
A as i,
|
|
598
|
+
J as j,
|
|
599
|
+
ve as k,
|
|
600
|
+
q as l,
|
|
601
|
+
Fe as m,
|
|
602
|
+
Ye as n
|
|
603
|
+
};
|
package/es/index.mjs
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { m as l, l as d, f as t, h as c, c as p, b as C, n as f, k as h, j as k, e as I, d as H } from "./index-964abda4.js";
|
|
3
|
+
import { a as g } from "./index-8bd8ff1f.js";
|
|
4
4
|
import "@done-coding/cli-utils";
|
|
5
|
-
import "node:
|
|
6
|
-
import "@done-coding/request-axios";
|
|
7
|
-
import "axios";
|
|
5
|
+
import "node:child_process";
|
|
8
6
|
import "node:fs";
|
|
9
7
|
import "node:path";
|
|
10
|
-
import "
|
|
8
|
+
import "@done-coding/request-axios";
|
|
9
|
+
import "axios";
|
|
11
10
|
export {
|
|
12
|
-
l as
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
c as
|
|
11
|
+
l as checkCommandCliInfo,
|
|
12
|
+
d as checkHandler,
|
|
13
|
+
t as cloneCommandCliInfo,
|
|
14
|
+
c as cloneHandler,
|
|
15
|
+
p as commandCliInfo,
|
|
16
|
+
g as crateAsSubcommand,
|
|
17
|
+
C as getTargetRepoUrl,
|
|
18
|
+
f as handler,
|
|
19
|
+
h as hooksCommandCliInfo,
|
|
20
|
+
k as hooksHandler,
|
|
21
|
+
I as initCommandCliInfo,
|
|
22
|
+
H as initHandler
|
|
16
23
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@done-coding/cli-git",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "git跨平台操作命令行工具",
|
|
5
5
|
"private": false,
|
|
6
6
|
"module": "es/index.mjs",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"license": "MIT",
|
|
52
52
|
"sideEffects": false,
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@done-coding/cli-inject": "^0.5.8
|
|
54
|
+
"@done-coding/cli-inject": "^0.5.8",
|
|
55
55
|
"@types/node": "^18.0.0",
|
|
56
56
|
"@types/yargs": "^17.0.28",
|
|
57
57
|
"rimraf": "^6.0.1",
|
|
@@ -63,9 +63,9 @@
|
|
|
63
63
|
"node": ">=18.0.0"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@done-coding/cli-utils": "^0.
|
|
66
|
+
"@done-coding/cli-utils": "^0.7.0",
|
|
67
67
|
"@done-coding/request-axios": "^1.1.1",
|
|
68
68
|
"axios": "^1.8.4"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "b4fb4f2380a14f72597a1dbfd1bbce22287ef02f"
|
|
71
71
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { CheckOptions, GitConfig } from '../types';
|
|
2
|
+
import { CheckReverseMergeWayEnum } from '../types';
|
|
3
|
+
import type { ArgumentsCamelCase, GitRebaseInfo, SubCliInfo, SupportGetCommitByHookName, YargsOptions } from "@done-coding/cli-utils";
|
|
4
|
+
import type { PositionalOptions } from "yargs";
|
|
5
|
+
export declare const getOptions: () => Record<string, YargsOptions>;
|
|
6
|
+
export declare const getPositionals: () => Record<string, PositionalOptions>;
|
|
7
|
+
/** 检测反向合并-通过git reflog action */
|
|
8
|
+
export declare const checkReverseMergeByReflogAction: ({ config, currentBranch, }: {
|
|
9
|
+
config: GitConfig;
|
|
10
|
+
currentBranch?: string | undefined;
|
|
11
|
+
}) => undefined;
|
|
12
|
+
/** 检测反向合并-通过提交信息 */
|
|
13
|
+
export declare const checkReverseMergeByCommitMsg: ({ config, currentBranch, commitMsg, rootDir, }: {
|
|
14
|
+
config: GitConfig;
|
|
15
|
+
currentBranch?: string | undefined;
|
|
16
|
+
commitMsg?: string | undefined;
|
|
17
|
+
rootDir: string;
|
|
18
|
+
}) => void;
|
|
19
|
+
/** 检测反向合并-通过提交记录 */
|
|
20
|
+
export declare const checkReverseMergeByCommitRecord: ({ config, currentBranch, }: {
|
|
21
|
+
config: GitConfig;
|
|
22
|
+
currentBranch?: string | undefined;
|
|
23
|
+
}) => void;
|
|
24
|
+
/** 检测反向变基 */
|
|
25
|
+
export declare const checkReverseRebase: ({ config, rebaseInfo, }: {
|
|
26
|
+
config: GitConfig;
|
|
27
|
+
rebaseInfo: GitRebaseInfo;
|
|
28
|
+
}) => undefined;
|
|
29
|
+
export type CheckReverseMergeHandlerParams = {
|
|
30
|
+
config: GitConfig;
|
|
31
|
+
rootDir: string;
|
|
32
|
+
way: CheckReverseMergeWayEnum.COMMIT_MSG;
|
|
33
|
+
hookName: SupportGetCommitByHookName;
|
|
34
|
+
} | {
|
|
35
|
+
config: GitConfig;
|
|
36
|
+
rootDir: string;
|
|
37
|
+
way: CheckReverseMergeWayEnum.REFLOG_ACTION;
|
|
38
|
+
} | {
|
|
39
|
+
config: GitConfig;
|
|
40
|
+
rootDir: string;
|
|
41
|
+
way: CheckReverseMergeWayEnum.COMMIT_RECORD;
|
|
42
|
+
} | {
|
|
43
|
+
config: GitConfig;
|
|
44
|
+
way: CheckReverseMergeWayEnum.PRE_REBASE;
|
|
45
|
+
args: string[];
|
|
46
|
+
};
|
|
47
|
+
/** 检测反向合并 */
|
|
48
|
+
export declare const checkReverseMergeHandler: (params: CheckReverseMergeHandlerParams) => Promise<void>;
|
|
49
|
+
/** 检测 */
|
|
50
|
+
export declare const handler: (argv: ArgumentsCamelCase<CheckOptions>) => Promise<void>;
|
|
51
|
+
export declare const commandCliInfo: SubCliInfo;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CliHandlerArgv, CliInfo, SubCliInfo } from "@done-coding/cli-utils";
|
|
2
|
+
import type { CloneOptions } from '../types';
|
|
3
|
+
export declare const getOptions: () => CliInfo["options"];
|
|
4
|
+
/** 位置参数 */
|
|
5
|
+
export declare const getPositionals: () => CliInfo["positionals"];
|
|
6
|
+
/** 克隆目标仓库 */
|
|
7
|
+
export declare const handler: (options: CliHandlerArgv<CloneOptions>) => Promise<void>;
|
|
8
|
+
export declare const commandCliInfo: SubCliInfo;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ArgumentsCamelCase, PositionalOptions } from "yargs";
|
|
2
|
+
import { type HooksOptions } from '../types';
|
|
3
|
+
import type { SubCliInfo, YargsOptions } from "@done-coding/cli-utils";
|
|
4
|
+
export declare const getOptions: () => Record<string, YargsOptions>;
|
|
5
|
+
export declare const getPositionals: () => Record<string, PositionalOptions>;
|
|
6
|
+
export declare const handler: (argv: ArgumentsCamelCase<HooksOptions>) => Promise<void>;
|
|
7
|
+
export declare const commandCliInfo: SubCliInfo;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { handler as initHandler, commandCliInfo as initCommandCliInfo } from "./init";
|
|
2
|
+
import { handler as cloneHandler, commandCliInfo as cloneCommandCliInfo } from "./clone";
|
|
3
|
+
import { handler as hooksHandler, commandCliInfo as hooksCommandCliInfo } from "./hooks";
|
|
4
|
+
import { handler as checkHandler, commandCliInfo as checkCommandCliInfo } from "./check";
|
|
5
|
+
import { SubcommandEnum } from '../types';
|
|
6
|
+
import { type CliHandlerArgv, type CliInfo } from "@done-coding/cli-utils";
|
|
7
|
+
export { initHandler, initCommandCliInfo, cloneHandler, cloneCommandCliInfo, hooksHandler, hooksCommandCliInfo, checkHandler, checkCommandCliInfo, };
|
|
8
|
+
export declare const handler: (command: SubcommandEnum, argv: CliHandlerArgv<any>) => Promise<void>;
|
|
9
|
+
export declare const commandCliInfo: Omit<CliInfo, "usage">;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/// <reference types="yargs" />
|
|
2
|
+
import type { ArgumentsCamelCase, SubCliInfo } from "@done-coding/cli-utils";
|
|
3
|
+
import { InitTypeEnum, type InitOptions } from '../types';
|
|
4
|
+
/** 获取初始化选项 */
|
|
5
|
+
export declare const getOptions: () => {
|
|
6
|
+
type: {
|
|
7
|
+
alias: string;
|
|
8
|
+
describe: string;
|
|
9
|
+
choices: InitTypeEnum[];
|
|
10
|
+
default: InitTypeEnum;
|
|
11
|
+
};
|
|
12
|
+
rootDir: import("yargs").Options;
|
|
13
|
+
configPath: import("yargs").Options;
|
|
14
|
+
};
|
|
15
|
+
export declare const handler: (argv: ArgumentsCamelCase<InitOptions> & {
|
|
16
|
+
/** 是否是子命令 */
|
|
17
|
+
isSubCommand?: boolean;
|
|
18
|
+
}) => Promise<void>;
|
|
19
|
+
export declare const commandCliInfo: SubCliInfo;
|
package/types/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from './handlers';
|
|
2
2
|
export { crateAsSubcommand } from "./main";
|
|
3
|
-
export { getTargetRepoUrl
|
|
3
|
+
export { getTargetRepoUrl } from "./utils";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ReadConfigFileOptions } from "@done-coding/cli-utils";
|
|
2
|
+
import { SubcommandEnum } from "./subcommand";
|
|
3
|
+
/** 检测类型 */
|
|
4
|
+
export declare enum CheckTypeEnum {
|
|
5
|
+
/** 反向提交 */
|
|
6
|
+
REVERSE_MERGE = "reverseMerge"
|
|
7
|
+
}
|
|
8
|
+
/** 检测反向方式枚举 */
|
|
9
|
+
export declare enum CheckReverseMergeWayEnum {
|
|
10
|
+
/** GIT_REFLOG_ACTION */
|
|
11
|
+
REFLOG_ACTION = "reflog-action",
|
|
12
|
+
/** 提交信息 */
|
|
13
|
+
COMMIT_MSG = "commit-msg",
|
|
14
|
+
/** 提交记录 */
|
|
15
|
+
COMMIT_RECORD = "commit-record",
|
|
16
|
+
/** 变基线 */
|
|
17
|
+
PRE_REBASE = "pre-rebase"
|
|
18
|
+
}
|
|
19
|
+
/** 检测反向 */
|
|
20
|
+
export type CheckOptions = ReadConfigFileOptions & {
|
|
21
|
+
type: CheckTypeEnum;
|
|
22
|
+
args: string[];
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* 禁止合并某个分支的检测选项
|
|
26
|
+
*/
|
|
27
|
+
export interface GitConfigCheckReverseMergeBranchConfig {
|
|
28
|
+
/** 包括变基操作 */
|
|
29
|
+
includeRebase: boolean;
|
|
30
|
+
/** 某个hash之后的提交 */
|
|
31
|
+
afterHash?: string;
|
|
32
|
+
/** 最多(检查日志数量) */
|
|
33
|
+
logCount: number;
|
|
34
|
+
}
|
|
35
|
+
/** 螃蟹git配置 */
|
|
36
|
+
export interface GitConfig {
|
|
37
|
+
[SubcommandEnum.CHECK]: {
|
|
38
|
+
[CheckTypeEnum.REVERSE_MERGE]: Record<string, GitConfigCheckReverseMergeBranchConfig>;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
import type { InitConfigFileOptions } from "@done-coding/cli-utils";
|
|
2
|
-
/** 子命令枚举 */
|
|
3
|
-
export declare enum SubcommandEnum {
|
|
4
|
-
/** 初始化配置文件 */
|
|
5
|
-
INIT = "init",
|
|
6
|
-
/** 克隆 */
|
|
7
|
-
CLONE = "clone"
|
|
8
|
-
}
|
|
9
|
-
/** 初始化选项 */
|
|
10
|
-
export type InitOptions = Pick<InitConfigFileOptions, "rootDir">;
|
|
11
1
|
/** Git 平台枚举 */
|
|
12
2
|
export declare enum GitPlatformEnum {
|
|
13
3
|
/** GitHub */
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { InitConfigFileOptions } from "@done-coding/cli-utils";
|
|
2
|
+
/** 初始化类型 */
|
|
3
|
+
export declare enum InitTypeEnum {
|
|
4
|
+
DEFAULT = "default",
|
|
5
|
+
CLONE_CONFIG = "cloneConfig"
|
|
6
|
+
}
|
|
7
|
+
/** 初始化选项 */
|
|
8
|
+
export interface InitOptions extends InitConfigFileOptions {
|
|
9
|
+
type?: InitTypeEnum;
|
|
10
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { GitConfig } from '../types';
|
|
2
|
+
import type { GitLogItemInfo, GitReflogItemInfo } from "@done-coding/cli-utils";
|
|
3
|
+
import { type GitMergeBranchInfo } from "@done-coding/cli-utils";
|
|
4
|
+
/** 获取检测反向合并配置map */
|
|
5
|
+
export declare const getCheckReverseMergeConfigMap: (config: GitConfig) => Record<string, import('../types').GitConfigCheckReverseMergeBranchConfig>;
|
|
6
|
+
/** 获取检测反向合并配置map类型 */
|
|
7
|
+
export type CheckReverseMergeConfigMap = ReturnType<typeof getCheckReverseMergeConfigMap>;
|
|
8
|
+
/** 获取检测反向合并配置的最大日志数量 */
|
|
9
|
+
export declare const getCheckReverseMergeMaxLogCount: (configMap: CheckReverseMergeConfigMap) => number;
|
|
10
|
+
/** 获取检测反向合并配置的最大索引map */
|
|
11
|
+
export declare const getCheckReverseMergeMaxIndexMap: (configMap: CheckReverseMergeConfigMap, logList: (GitLogItemInfo | GitReflogItemInfo)[]) => Record<string, number>;
|
|
12
|
+
/**
|
|
13
|
+
* 检测是否是反向合并
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
export declare const checkIsReverseMerge: ({ mergeInfo, configMap, currentBranch, }: {
|
|
17
|
+
mergeInfo?: GitMergeBranchInfo | undefined;
|
|
18
|
+
configMap: CheckReverseMergeConfigMap;
|
|
19
|
+
currentBranch?: string | undefined;
|
|
20
|
+
}) => boolean | undefined;
|
package/types/utils/config.d.ts
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { HooksNameEnum } from "@done-coding/cli-utils";
|
|
2
|
+
/** 支持的git hooks名称 */
|
|
3
|
+
export declare const SUPPORT_HOOKS_NAME: HooksNameEnum[];
|
|
4
|
+
/** 支持的检查反向合并的git hooks名称 */
|
|
5
|
+
export declare const SUPPORT_CHECK_REVERSE_MERGE_HOOKS_NAME: readonly [HooksNameEnum.PRE_MERGE_COMMIT, HooksNameEnum.PREPARE_COMMIT_MSG, HooksNameEnum.POST_MERGE, HooksNameEnum.PRE_PUSH, HooksNameEnum.PRE_REBASE];
|
|
6
|
+
/** 支持的检查反向合并的git hooks名称类型 */
|
|
7
|
+
export type SupportCheckReverseMergeHooksNameType = (typeof SUPPORT_CHECK_REVERSE_MERGE_HOOKS_NAME)[number];
|
package/types/utils/index.d.ts
CHANGED
package/types/utils/path.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PromptObject } from "@done-coding/cli-utils";
|
|
2
|
-
import { GitPlatformEnum } from
|
|
2
|
+
import { GitPlatformEnum } from '../types';
|
|
3
3
|
/** git平台选择表单 */
|
|
4
4
|
export declare const getPlatformForm: (initialValue?: GitPlatformEnum) => PromptObject<string>;
|
|
5
5
|
/** git用户名表单 */
|
package/es/clone-11819b7f.js
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { createRequest as $ } from "@done-coding/request-axios";
|
|
3
|
-
import C from "axios";
|
|
4
|
-
import { lookForParentTarget as S, log as a, decryptAES as I, encryptAES as P, xPrompts as m } from "@done-coding/cli-utils";
|
|
5
|
-
import f from "node:fs";
|
|
6
|
-
import d from "node:path";
|
|
7
|
-
import { execSync as k } from "node:child_process";
|
|
8
|
-
var v = /* @__PURE__ */ ((e) => (e.INIT = "init", e.CLONE = "clone", e))(v || {}), l = /* @__PURE__ */ ((e) => (e.GITHUB = "github", e.GITEE = "gitee", e))(l || {});
|
|
9
|
-
const w = 3e4, h = Math.random(), G = {
|
|
10
|
-
timeout: w,
|
|
11
|
-
getBusinessCode() {
|
|
12
|
-
return h;
|
|
13
|
-
},
|
|
14
|
-
getBusinessMsg(e) {
|
|
15
|
-
return e.statusText;
|
|
16
|
-
},
|
|
17
|
-
getBusinessData(e) {
|
|
18
|
-
return e.data;
|
|
19
|
-
},
|
|
20
|
-
businessSuccessCodeList: [h],
|
|
21
|
-
axios: C
|
|
22
|
-
}, y = $({
|
|
23
|
-
basePath: " https://gitee.com",
|
|
24
|
-
...G
|
|
25
|
-
}), U = $({
|
|
26
|
-
basePath: "https://api.github.com",
|
|
27
|
-
...G
|
|
28
|
-
}), B = ({
|
|
29
|
-
username: e
|
|
30
|
-
}) => y({
|
|
31
|
-
url: `/api/v5/users/${e}/repos`,
|
|
32
|
-
method: "GET"
|
|
33
|
-
}), F = ({
|
|
34
|
-
accessToken: e
|
|
35
|
-
}) => y({
|
|
36
|
-
url: "/api/v5/user/repos",
|
|
37
|
-
method: "GET",
|
|
38
|
-
params: {
|
|
39
|
-
access_token: e,
|
|
40
|
-
per_page: 100,
|
|
41
|
-
page: 1,
|
|
42
|
-
sort: "updated"
|
|
43
|
-
}
|
|
44
|
-
}), _ = ({
|
|
45
|
-
username: e
|
|
46
|
-
}) => U({
|
|
47
|
-
url: `/users/${e}/repos`,
|
|
48
|
-
method: "GET"
|
|
49
|
-
}), x = ({
|
|
50
|
-
accessToken: e
|
|
51
|
-
}) => U({
|
|
52
|
-
url: "/user/repos",
|
|
53
|
-
method: "GET",
|
|
54
|
-
headers: {
|
|
55
|
-
Authorization: `Bearer ${e}`
|
|
56
|
-
},
|
|
57
|
-
params: {
|
|
58
|
-
per_page: 100,
|
|
59
|
-
page: 1,
|
|
60
|
-
sort: "updated"
|
|
61
|
-
}
|
|
62
|
-
}), N = {
|
|
63
|
-
name: "@done-coding/cli-git",
|
|
64
|
-
version: "0.5.5-alpha.1",
|
|
65
|
-
description: "git跨平台操作命令行工具",
|
|
66
|
-
cliConfig: {
|
|
67
|
-
namespaceDir: ".done-coding",
|
|
68
|
-
moduleName: "git"
|
|
69
|
-
}
|
|
70
|
-
}, {
|
|
71
|
-
cliConfig: { namespaceDir: O, moduleName: R }
|
|
72
|
-
} = N, A = `./${O}/${R}`, E = (e) => `${A}/.${e}`, b = ({ platform: e, username: t }) => `${e}/${t}`, D = (e) => {
|
|
73
|
-
const { platform: t } = e, s = E(t), n = S(s, {
|
|
74
|
-
isFindFarthest: !1
|
|
75
|
-
});
|
|
76
|
-
if (!n) {
|
|
77
|
-
a.warn("配置文件不存在");
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
const o = `${n}/${s}`, c = f.readFileSync(o, "utf-8"), i = b(e), u = I({ encryptedText: c, secretKey: i });
|
|
81
|
-
if (!u) {
|
|
82
|
-
a.warn("配置文件解密失败");
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
return JSON.parse(u);
|
|
86
|
-
}, V = ({
|
|
87
|
-
rootDir: e,
|
|
88
|
-
username: t,
|
|
89
|
-
platform: s,
|
|
90
|
-
accessToken: n
|
|
91
|
-
}) => {
|
|
92
|
-
const o = E(s), i = JSON.stringify({
|
|
93
|
-
accessToken: n
|
|
94
|
-
}), u = b({ platform: s, username: t }), p = P({ text: i, secretKey: u }), g = d.join(e, o);
|
|
95
|
-
f.mkdirSync(d.dirname(g), {
|
|
96
|
-
recursive: !0
|
|
97
|
-
}), f.writeFileSync(g, p, "utf-8"), a.success(`配置信息保存成功 ${g}`);
|
|
98
|
-
}, T = [
|
|
99
|
-
{ title: "GitHub", value: l.GITHUB },
|
|
100
|
-
{ title: "Gitee", value: l.GITEE }
|
|
101
|
-
], H = (e) => {
|
|
102
|
-
let t = 0;
|
|
103
|
-
if (e) {
|
|
104
|
-
const s = T.findIndex(
|
|
105
|
-
(n) => n.value === e
|
|
106
|
-
);
|
|
107
|
-
s >= 0 && (t = s);
|
|
108
|
-
}
|
|
109
|
-
return {
|
|
110
|
-
type: "select",
|
|
111
|
-
name: "platform",
|
|
112
|
-
message: "选择git平台",
|
|
113
|
-
choices: T,
|
|
114
|
-
initial: t
|
|
115
|
-
};
|
|
116
|
-
}, j = (e) => ({
|
|
117
|
-
type: "text",
|
|
118
|
-
name: "username",
|
|
119
|
-
message: "请输入用户名",
|
|
120
|
-
format: (t) => t.trim(),
|
|
121
|
-
validate: (t) => t.length > 0 || "用户名不能为空",
|
|
122
|
-
initial: e
|
|
123
|
-
}), W = {
|
|
124
|
-
type: "password",
|
|
125
|
-
name: "accessToken",
|
|
126
|
-
message: "请输入git access token",
|
|
127
|
-
format: (e) => e.trim(),
|
|
128
|
-
validate: (e) => e.length > 0 || "access token不能为空"
|
|
129
|
-
}, L = async ({
|
|
130
|
-
platform: e,
|
|
131
|
-
username: t
|
|
132
|
-
} = {}) => {
|
|
133
|
-
const s = {
|
|
134
|
-
platform: e,
|
|
135
|
-
username: t
|
|
136
|
-
};
|
|
137
|
-
e || (s.platform = (await m(H())).platform), t || (s.username = (await m(j())).username);
|
|
138
|
-
const { platform: n, username: o } = s;
|
|
139
|
-
let c = [];
|
|
140
|
-
const i = D({
|
|
141
|
-
username: o,
|
|
142
|
-
platform: n
|
|
143
|
-
});
|
|
144
|
-
let u = i == null ? void 0 : i.accessToken;
|
|
145
|
-
a.stage(`正在获取${o}的${n}仓库列表...`);
|
|
146
|
-
const p = {
|
|
147
|
-
username: o,
|
|
148
|
-
accessToken: u
|
|
149
|
-
};
|
|
150
|
-
switch (s.platform) {
|
|
151
|
-
case l.GITHUB: {
|
|
152
|
-
c = (await (p.accessToken ? x : _)(p)).data.map((r) => ({
|
|
153
|
-
name: r.name,
|
|
154
|
-
httpUrl: r.clone_url,
|
|
155
|
-
sshUrl: r.ssh_url,
|
|
156
|
-
description: r.description || ""
|
|
157
|
-
}));
|
|
158
|
-
break;
|
|
159
|
-
}
|
|
160
|
-
case l.GITEE: {
|
|
161
|
-
c = (await (p.accessToken ? F : B)(p)).data.map((r) => ({
|
|
162
|
-
name: r.name,
|
|
163
|
-
httpUrl: r.html_url,
|
|
164
|
-
sshUrl: r.ssh_url,
|
|
165
|
-
description: r.description || ""
|
|
166
|
-
}));
|
|
167
|
-
break;
|
|
168
|
-
}
|
|
169
|
-
default:
|
|
170
|
-
return a.error(`未知平台${n}`), process.exit(1);
|
|
171
|
-
}
|
|
172
|
-
if (a.success(`获取${o}的${n}仓库列表成功`), c.length === 0) {
|
|
173
|
-
a.warn(`${o} 可获取${n}仓库列表为空`);
|
|
174
|
-
return;
|
|
175
|
-
} else
|
|
176
|
-
a.stage(`共${c.length}个仓库`);
|
|
177
|
-
const { repoUrl: g } = await m({
|
|
178
|
-
name: "repoUrl",
|
|
179
|
-
type: "select",
|
|
180
|
-
message: "选择仓库",
|
|
181
|
-
choices: c.map((r) => ({
|
|
182
|
-
title: `${r.name} ${r.description}`,
|
|
183
|
-
value: r.sshUrl
|
|
184
|
-
}))
|
|
185
|
-
});
|
|
186
|
-
return g;
|
|
187
|
-
}, X = () => ({
|
|
188
|
-
projectName: {
|
|
189
|
-
type: "string",
|
|
190
|
-
alias: "p",
|
|
191
|
-
describe: "项目名称"
|
|
192
|
-
}
|
|
193
|
-
}), Y = () => ({
|
|
194
|
-
platform: {
|
|
195
|
-
describe: "选择git平台",
|
|
196
|
-
type: "string",
|
|
197
|
-
choices: [l.GITHUB, l.GITEE]
|
|
198
|
-
},
|
|
199
|
-
username: {
|
|
200
|
-
describe: "git平台用户名",
|
|
201
|
-
type: "string"
|
|
202
|
-
}
|
|
203
|
-
}), Z = async (e) => {
|
|
204
|
-
const t = await L(e), { projectName: s } = e;
|
|
205
|
-
k(
|
|
206
|
-
`git clone ${t} ${s ? `${s} ` : ""}--depth=1`,
|
|
207
|
-
{ stdio: "inherit" }
|
|
208
|
-
), a.success(`克隆${t}成功`);
|
|
209
|
-
};
|
|
210
|
-
export {
|
|
211
|
-
l as G,
|
|
212
|
-
v as S,
|
|
213
|
-
j as a,
|
|
214
|
-
W as b,
|
|
215
|
-
Z as c,
|
|
216
|
-
X as d,
|
|
217
|
-
Y as e,
|
|
218
|
-
L as f,
|
|
219
|
-
H as g,
|
|
220
|
-
N as i,
|
|
221
|
-
V as s
|
|
222
|
-
};
|
package/es/index-49e07bde.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { getRootDirOptions as p, xPrompts as e, log as C, _curry as r, createSubcommand as c, createMainCommand as f } from "@done-coding/cli-utils";
|
|
3
|
-
import { g, a as I, b, s as h, S as t, c as N, d as O, e as w, i as T } from "./clone-11819b7f.js";
|
|
4
|
-
import $ from "node:os";
|
|
5
|
-
const y = () => p($.homedir()), E = async (o) => {
|
|
6
|
-
const { rootDir: n } = o, { platform: s } = await e(g()), { username: l } = await e(I()), { accessToken: u } = await e(b);
|
|
7
|
-
await h({
|
|
8
|
-
rootDir: n,
|
|
9
|
-
platform: s,
|
|
10
|
-
username: l,
|
|
11
|
-
accessToken: u
|
|
12
|
-
});
|
|
13
|
-
}, i = async (o, n) => {
|
|
14
|
-
switch (o) {
|
|
15
|
-
case t.INIT:
|
|
16
|
-
return E(n);
|
|
17
|
-
case t.CLONE:
|
|
18
|
-
return N(n);
|
|
19
|
-
default:
|
|
20
|
-
return C.error(`无效的命令: ${o}`), process.exit(1);
|
|
21
|
-
}
|
|
22
|
-
}, {
|
|
23
|
-
version: x,
|
|
24
|
-
description: A,
|
|
25
|
-
cliConfig: { moduleName: a }
|
|
26
|
-
} = T, F = {
|
|
27
|
-
command: t.INIT,
|
|
28
|
-
describe: "初始化git配置文件",
|
|
29
|
-
options: y(),
|
|
30
|
-
handler: r(i)(
|
|
31
|
-
t.INIT
|
|
32
|
-
)
|
|
33
|
-
}, L = {
|
|
34
|
-
command: `${t.CLONE} <platform> <username>`,
|
|
35
|
-
describe: "从选择的git平台克隆代码",
|
|
36
|
-
options: O(),
|
|
37
|
-
positionals: w(),
|
|
38
|
-
handler: r(i)(
|
|
39
|
-
t.CLONE
|
|
40
|
-
)
|
|
41
|
-
}, m = {
|
|
42
|
-
describe: A,
|
|
43
|
-
version: x,
|
|
44
|
-
subcommands: [F, L].map(c),
|
|
45
|
-
demandCommandCount: 1
|
|
46
|
-
}, d = (o = !1) => {
|
|
47
|
-
const n = o ? a : void 0, s = `$0${o ? ` ${a}` : ""} <command> [options]`;
|
|
48
|
-
return { command: n, usage: s };
|
|
49
|
-
}, v = async () => f({
|
|
50
|
-
...m,
|
|
51
|
-
...d()
|
|
52
|
-
}), D = () => c({
|
|
53
|
-
...m,
|
|
54
|
-
...d(!0)
|
|
55
|
-
});
|
|
56
|
-
export {
|
|
57
|
-
D as a,
|
|
58
|
-
v as c,
|
|
59
|
-
i as h
|
|
60
|
-
};
|
package/types/handler.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { SubcommandEnum } from './utils';
|
|
2
|
-
import type { InitOptions, CloneOptions } from './utils';
|
|
3
|
-
import type { CliHandlerArgv } from "@done-coding/cli-utils";
|
|
4
|
-
/** 子命令处理函数 */
|
|
5
|
-
export declare const handler: (command: SubcommandEnum, argv: CliHandlerArgv<InitOptions | CloneOptions>) => Promise<void>;
|
package/types/utils/clone.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type CloneOptions } from "./types";
|
|
2
|
-
import type { CliInfo } from "@done-coding/cli-utils";
|
|
3
|
-
export declare const getCloneOptions: () => CliInfo["options"];
|
|
4
|
-
/** 获取克隆命令的位置参数 */
|
|
5
|
-
export declare const getClonePositionals: () => CliInfo["positionals"];
|
|
6
|
-
/** 克隆目标仓库 */
|
|
7
|
-
export declare const cloneHandler: (options: CloneOptions) => Promise<void>;
|
package/types/utils/init.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/// <reference types="yargs" />
|
|
2
|
-
import type { CliHandlerArgv } from "@done-coding/cli-utils";
|
|
3
|
-
import type { InitOptions } from "./types";
|
|
4
|
-
/** 获取初始化选项 */
|
|
5
|
-
export declare const getInitOptions: () => {
|
|
6
|
-
rootDir: import("yargs").Options;
|
|
7
|
-
};
|
|
8
|
-
/** 初始化命令处理器 */
|
|
9
|
-
export declare const initHandler: (argv: CliHandlerArgv<InitOptions>) => Promise<void>;
|