@cc123hh/gitee-cli 0.3.0 → 0.4.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/README.md +21 -3
- package/bin/gitee.js +296 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -163,12 +163,24 @@ gitee push --public -d "我的小工具"
|
|
|
163
163
|
### Issue / Pull Request
|
|
164
164
|
|
|
165
165
|
```bash
|
|
166
|
-
gitee issues emb-cli
|
|
166
|
+
gitee issues emb-cli # 列出 Issue
|
|
167
167
|
gitee issues emb-cli -s all -n 50
|
|
168
|
+
gitee issue view emb-cli IKVADU # 查看详情
|
|
169
|
+
gitee issue create emb-cli -t "发现bug" -b "复现步骤" -l bug -a 用户名 # 创建
|
|
170
|
+
gitee issue edit emb-cli IKVADU -t "新标题" -b "新正文" -l bug,docs # 修改
|
|
171
|
+
gitee issue edit emb-cli IKVADU -f 正文.md # 正文从 UTF-8 文件读(与 -b 互斥)
|
|
172
|
+
gitee issue close emb-cli IKVADU # 关闭(open 为重开)
|
|
173
|
+
gitee issue comment emb-cli IKVADU -m "已修复" # 加评论
|
|
174
|
+
gitee close emb-cli IKVADU # 顶层快捷:关闭 / 重开
|
|
175
|
+
gitee reopen emb-cli IKVADU
|
|
168
176
|
gitee prs emb-cli
|
|
169
177
|
```
|
|
170
178
|
|
|
171
|
-
`repo` 参数写 `仓库名` 会自动补上你的用户名,也可以写完整的 `owner/repo
|
|
179
|
+
`repo` 参数写 `仓库名` 会自动补上你的用户名,也可以写完整的 `owner/repo`;
|
|
180
|
+
Issue 相关命令省略 `repo` 时取当前目录同名仓库,只写编号也能定位
|
|
181
|
+
(如 `gitee issue view IKVADU`)。Issue 编号是 Gitee 生成的字符串标识
|
|
182
|
+
(如 `IKVADU`),带不带 `#` 前缀都可以(shell 里 `#` 要加引号)。
|
|
183
|
+
Gitee 无删除 Issue 的接口(已实测 405),`issue delete` 不提供。
|
|
172
184
|
|
|
173
185
|
## 📋 参数
|
|
174
186
|
|
|
@@ -176,7 +188,13 @@ gitee prs emb-cli
|
|
|
176
188
|
|---|---|---|
|
|
177
189
|
| `-n/--limit` | list / issues / prs | 返回条数 |
|
|
178
190
|
| `--json` | list | 输出原始 JSON |
|
|
179
|
-
| `-s/--state` | issues / prs | `open`
|
|
191
|
+
| `-s/--state` | issues / prs / issue | 列表筛选 `open`/`closed`/`all`;`issue edit` 修改状态 `open`/`progressing`/`closed` |
|
|
192
|
+
| `-t/--title` | issue create / edit | 标题(create 必填) |
|
|
193
|
+
| `-b/--body` | issue create / edit | 正文(与 `-f` 互斥) |
|
|
194
|
+
| `-f/--file` | issue create / edit / comment | 从 UTF-8 文件读正文/评论 |
|
|
195
|
+
| `-l/--labels` | issue create / edit | 标签,逗号分隔 |
|
|
196
|
+
| `-a/--assignee` | issue create / edit | 负责人 username |
|
|
197
|
+
| `-m/--message` | issue comment | 评论内容 |
|
|
180
198
|
| `-y/--yes` | delete | 跳过确认 |
|
|
181
199
|
| `-d/--description` | create / push | 仓库简介 |
|
|
182
200
|
| `--public` | create / push | 目标可见性 |
|
package/bin/gitee.js
CHANGED
|
@@ -314,6 +314,189 @@ async function cmdPrs(client, opts) {
|
|
|
314
314
|
return EXIT_OK;
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
+
// Issue 编号是 Gitee 自动生成的字符串标识(如 IKVADU),不是数字
|
|
318
|
+
const ISSUE_STATE_TEXT = {
|
|
319
|
+
open: "开启", progress: "进行中", closed: "已关闭", rejected: "已拒绝",
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
function issueStateText(state) {
|
|
323
|
+
return ISSUE_STATE_TEXT[state] || state || "?";
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// 统一解析 issue 单条操作的位置参数:
|
|
327
|
+
// - 两个位置参数:repo + 编号
|
|
328
|
+
// - 只给一个:视为编号,仓库取当前目录同名仓库
|
|
329
|
+
// - 编号容忍 # 前缀(用户习惯写 #IKVADU)
|
|
330
|
+
function parseIssueArg(opts) {
|
|
331
|
+
let repo = opts.repo;
|
|
332
|
+
let number = opts.number;
|
|
333
|
+
const repoEmpty = repo === undefined || repo === null || repo === "";
|
|
334
|
+
const numEmpty = number === undefined || number === null || number === "";
|
|
335
|
+
if (numEmpty && repoEmpty) return null;
|
|
336
|
+
if (numEmpty) {
|
|
337
|
+
number = repo;
|
|
338
|
+
repo = undefined;
|
|
339
|
+
}
|
|
340
|
+
number = String(number).trim().replace(/^#/, "");
|
|
341
|
+
if (!number) return null;
|
|
342
|
+
return { repo: repo === undefined || repo === null ? "" : String(repo).trim(), number };
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
async function issueTarget(opts, client) {
|
|
346
|
+
const pos = parseIssueArg(opts);
|
|
347
|
+
if (!pos) return null;
|
|
348
|
+
const full = await splitRepo(pos.repo || path.basename(process.cwd()), client);
|
|
349
|
+
return { full, number: pos.number };
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function issueUsageHint(action) {
|
|
353
|
+
return `错误:缺少 Issue 编号。用法:gitee ${action} [<仓库>] <编号>`
|
|
354
|
+
+ `(仓库省略时取当前目录同名仓库)`;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function printIssue(it) {
|
|
358
|
+
console.log(`编号: #${it.number}`);
|
|
359
|
+
console.log(`标题: ${it.title}`);
|
|
360
|
+
console.log(`状态: ${it.state}(${issueStateText(it.state)})`);
|
|
361
|
+
console.log(`作者: ${(it.user && it.user.login) || "?"}`);
|
|
362
|
+
const labels = (it.labels || []).map((l) => l.name || l).join(", ");
|
|
363
|
+
console.log(`标签: ${labels || "(无)"}`);
|
|
364
|
+
console.log(`评论: ${it.comments ?? 0} 条`);
|
|
365
|
+
console.log(`创建: ${it.created_at}`);
|
|
366
|
+
console.log(`更新: ${it.updated_at}`);
|
|
367
|
+
if (it.finished_at) console.log(`完成: ${it.finished_at}`);
|
|
368
|
+
console.log(`链接: ${it.html_url}`);
|
|
369
|
+
console.log("正文:");
|
|
370
|
+
console.log(it.body || "(无)");
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
async function cmdIssue(client, opts) {
|
|
374
|
+
const target = await issueTarget(opts, client);
|
|
375
|
+
if (!target) {
|
|
376
|
+
console.error(issueUsageHint("issue view"));
|
|
377
|
+
return EXIT_USAGE;
|
|
378
|
+
}
|
|
379
|
+
const it = await issueGet(client, target.full, target.number);
|
|
380
|
+
printIssue(it);
|
|
381
|
+
return EXIT_OK;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// ---------- Issue 写接口(路径不含 repo 段,仓库以表单参数 repo 传) ---------- //
|
|
385
|
+
function issueOwnerRepo(full) {
|
|
386
|
+
const [owner, repoName] = full.split("/");
|
|
387
|
+
return { owner, repoName };
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function issueGet(client, full, number) {
|
|
391
|
+
return client.get(`/repos/${full}/issues/${encodeURIComponent(number)}`);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function issuePatch(client, full, number, form) {
|
|
395
|
+
// 统一注入表单 repo:Gitee 更新接口路径不含 repo 段(与 GitHub 不同)
|
|
396
|
+
const { owner, repoName } = issueOwnerRepo(full);
|
|
397
|
+
return client.patch(`/repos/${owner}/issues/${encodeURIComponent(number)}`,
|
|
398
|
+
{ repo: repoName, ...form });
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// -b 正文 与 -f 文件正文 互斥;-f 读取 UTF-8 文件内容作为正文
|
|
402
|
+
function resolveBodyArg(opts) {
|
|
403
|
+
if (opts.body !== undefined && opts.file !== undefined) {
|
|
404
|
+
console.error("错误:-b/--body 与 -f/--file 只能二选一");
|
|
405
|
+
return { error: true };
|
|
406
|
+
}
|
|
407
|
+
if (opts.file !== undefined) {
|
|
408
|
+
try {
|
|
409
|
+
return { body: fs.readFileSync(opts.file, "utf8") };
|
|
410
|
+
} catch (e) {
|
|
411
|
+
console.error(`错误:无法读取正文文件 ${opts.file}:${e.message}`);
|
|
412
|
+
return { error: true };
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return { body: opts.body };
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
async function cmdIssueCreate(client, opts) {
|
|
419
|
+
if (!opts.title) {
|
|
420
|
+
console.error("错误:创建 Issue 需要 -t/--title 标题");
|
|
421
|
+
return EXIT_USAGE;
|
|
422
|
+
}
|
|
423
|
+
const bodyArg = resolveBodyArg(opts);
|
|
424
|
+
if (bodyArg.error) return EXIT_USAGE;
|
|
425
|
+
const full = await parseRepoArg(opts, client);
|
|
426
|
+
const { owner, repoName } = issueOwnerRepo(full);
|
|
427
|
+
const form = { repo: repoName, title: opts.title };
|
|
428
|
+
if (bodyArg.body !== undefined && bodyArg.body !== null) form.body = bodyArg.body;
|
|
429
|
+
if (opts.labels) form.labels = opts.labels;
|
|
430
|
+
if (opts.assignee) form.assignee = opts.assignee;
|
|
431
|
+
const it = await client.post(`/repos/${owner}/issues`, form);
|
|
432
|
+
console.log(`已创建: #${it.number} ${it.title}`);
|
|
433
|
+
console.log(`链接: ${it.html_url}`);
|
|
434
|
+
return EXIT_OK;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async function cmdIssueEdit(client, opts) {
|
|
438
|
+
const target = await issueTarget(opts, client);
|
|
439
|
+
if (!target) {
|
|
440
|
+
console.error(issueUsageHint("issue edit"));
|
|
441
|
+
return EXIT_USAGE;
|
|
442
|
+
}
|
|
443
|
+
const bodyArg = resolveBodyArg(opts);
|
|
444
|
+
if (bodyArg.error) return EXIT_USAGE;
|
|
445
|
+
const form = {};
|
|
446
|
+
if (opts.title !== undefined) form.title = opts.title;
|
|
447
|
+
if (bodyArg.body !== undefined && bodyArg.body !== null) form.body = bodyArg.body;
|
|
448
|
+
if (opts.state !== undefined) form.state = opts.state;
|
|
449
|
+
if (opts.labels !== undefined) form.labels = opts.labels;
|
|
450
|
+
if (opts.assignee !== undefined) form.assignee = opts.assignee;
|
|
451
|
+
// 不带任何修改参数时按查看处理,避免空 PATCH 造成误解
|
|
452
|
+
if (!Object.keys(form).length) {
|
|
453
|
+
const it = await issueGet(client, target.full, target.number);
|
|
454
|
+
printIssue(it);
|
|
455
|
+
return EXIT_OK;
|
|
456
|
+
}
|
|
457
|
+
await issuePatch(client, target.full, target.number, form);
|
|
458
|
+
const it = await issueGet(client, target.full, target.number);
|
|
459
|
+
printIssue(it);
|
|
460
|
+
return EXIT_OK;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
async function cmdIssueComment(client, opts) {
|
|
464
|
+
if (opts.message === undefined && opts.file === undefined) {
|
|
465
|
+
console.error("错误:评论内容用 -m/--message 给出(或 -f/--file 从文件读)");
|
|
466
|
+
return EXIT_USAGE;
|
|
467
|
+
}
|
|
468
|
+
const bodyArg = resolveBodyArg({ body: opts.message, file: opts.file });
|
|
469
|
+
if (bodyArg.error) return EXIT_USAGE;
|
|
470
|
+
if (!bodyArg.body) {
|
|
471
|
+
console.error("错误:评论内容不能为空");
|
|
472
|
+
return EXIT_USAGE;
|
|
473
|
+
}
|
|
474
|
+
const target = await issueTarget(opts, client);
|
|
475
|
+
if (!target) {
|
|
476
|
+
console.error(issueUsageHint("issue comment"));
|
|
477
|
+
return EXIT_USAGE;
|
|
478
|
+
}
|
|
479
|
+
const c = await client.post(
|
|
480
|
+
`/repos/${target.full}/issues/${encodeURIComponent(target.number)}/comments`,
|
|
481
|
+
{ body: bodyArg.body });
|
|
482
|
+
console.log(`已评论: #${target.number}(评论 id ${c.id})`);
|
|
483
|
+
if (c.html_url) console.log(`链接: ${c.html_url}`);
|
|
484
|
+
return EXIT_OK;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
async function cmdSetIssueState(client, opts, state, hint = "close") {
|
|
488
|
+
const target = await issueTarget(opts, client);
|
|
489
|
+
if (!target) {
|
|
490
|
+
console.error(issueUsageHint(hint));
|
|
491
|
+
return EXIT_USAGE;
|
|
492
|
+
}
|
|
493
|
+
const { full, number } = target;
|
|
494
|
+
await issuePatch(client, full, number, { state });
|
|
495
|
+
const it = await issueGet(client, full, number);
|
|
496
|
+
console.log(`#${it.number} [${issueStateText(it.state)}] ${it.title}`);
|
|
497
|
+
return EXIT_OK;
|
|
498
|
+
}
|
|
499
|
+
|
|
317
500
|
function runGit(args, cwd) {
|
|
318
501
|
const r = spawnSync("git", args, { cwd, encoding: "utf8" });
|
|
319
502
|
return { code: r.status, out: r.stdout || "", err: r.stderr || "" };
|
|
@@ -395,6 +578,82 @@ const STATE_OPTS = [
|
|
|
395
578
|
{ short: "-n", long: "--limit", dest: "limit", arg: "int", default: 20, help: "条数(默认 20)" },
|
|
396
579
|
];
|
|
397
580
|
|
|
581
|
+
// ---- Issue 动作族共用的选项与位置参数 ---- //
|
|
582
|
+
const ISSUE_STATE_OPT = [
|
|
583
|
+
{ short: "-s", long: "--state", dest: "state", arg: "value",
|
|
584
|
+
choices: ["open", "progressing", "closed"],
|
|
585
|
+
help: "状态:open 开启 / progressing 进行中 / closed 关闭" },
|
|
586
|
+
];
|
|
587
|
+
const ISSUE_BODY_OPTS = [
|
|
588
|
+
{ short: "-b", long: "--body", dest: "body", arg: "value", help: "正文(与 -f 二选一)" },
|
|
589
|
+
{ short: "-f", long: "--file", dest: "file", arg: "value", help: "从 UTF-8 文件读正文" },
|
|
590
|
+
];
|
|
591
|
+
const ISSUE_META_OPTS = [
|
|
592
|
+
{ short: "-l", long: "--labels", dest: "labels", arg: "value",
|
|
593
|
+
help: "标签,逗号分隔(如 bug,docs)" },
|
|
594
|
+
{ short: "-a", long: "--assignee", dest: "assignee", arg: "value", help: "负责人 username" },
|
|
595
|
+
];
|
|
596
|
+
const ISSUE_POS = [
|
|
597
|
+
{ dest: "repo", required: false, help: "仓库名或 owner/repo(默认当前目录同名仓库)" },
|
|
598
|
+
{ dest: "number", required: false, help: "Issue 编号(字符串标识,如 IKVADU,可带 #)" },
|
|
599
|
+
];
|
|
600
|
+
|
|
601
|
+
const ISSUE_FAMILY_HELP = `用法:gitee issue <动作> [参数]
|
|
602
|
+
|
|
603
|
+
动作:
|
|
604
|
+
view 查看 Issue 详情 gitee issue view [<repo>] <编号>
|
|
605
|
+
create 创建 Issue gitee issue create [<repo>] -t 标题 [-b|-f 正文] [-l 标签] [-a 负责人]
|
|
606
|
+
edit 修改 Issue gitee issue edit [<repo>] <编号> [-t 标题] [-b|-f 正文] [-s 状态] [-l 标签] [-a 负责人]
|
|
607
|
+
open 重开 Issue gitee issue open [<repo>] <编号>
|
|
608
|
+
close 关闭 Issue gitee issue close [<repo>] <编号>
|
|
609
|
+
comment 加评论 gitee issue comment [<repo>] <编号> -m 内容|-f 文件
|
|
610
|
+
|
|
611
|
+
用 gitee issue <动作> -h 查看各动作详情。`;
|
|
612
|
+
|
|
613
|
+
const ISSUE_ACTIONS = {
|
|
614
|
+
view: {
|
|
615
|
+
run: (client, o) => cmdIssue(client, o),
|
|
616
|
+
spec: spec("用法:gitee issue view [<repo>] <编号>", "查看 Issue 详情",
|
|
617
|
+
clientOpts(), ISSUE_POS),
|
|
618
|
+
},
|
|
619
|
+
create: {
|
|
620
|
+
run: (client, o) => cmdIssueCreate(client, o),
|
|
621
|
+
spec: spec("用法:gitee issue create [<repo>] -t 标题 [-b 正文|-f 文件] [-l 标签] [-a 负责人]",
|
|
622
|
+
"创建 Issue(Gitee 无删除接口,建前想清楚)",
|
|
623
|
+
[{ short: "-t", long: "--title", dest: "title", arg: "value", required: true,
|
|
624
|
+
help: "标题(必填)" },
|
|
625
|
+
...ISSUE_BODY_OPTS, ...ISSUE_META_OPTS, ...clientOpts()],
|
|
626
|
+
[{ dest: "repo", required: false, help: "仓库名或 owner/repo(默认当前目录同名仓库)" }]),
|
|
627
|
+
},
|
|
628
|
+
edit: {
|
|
629
|
+
run: (client, o) => cmdIssueEdit(client, o),
|
|
630
|
+
spec: spec("用法:gitee issue edit [<repo>] <编号> [-t 标题] [-b|-f 正文] [-s 状态] [-l 标签] [-a 负责人]",
|
|
631
|
+
"修改 Issue(不带任何修改参数时等于 view)",
|
|
632
|
+
[{ short: "-t", long: "--title", dest: "title", arg: "value", help: "新标题" },
|
|
633
|
+
...ISSUE_BODY_OPTS, ...ISSUE_STATE_OPT, ...ISSUE_META_OPTS, ...clientOpts()],
|
|
634
|
+
ISSUE_POS),
|
|
635
|
+
},
|
|
636
|
+
open: {
|
|
637
|
+
run: (client, o) => cmdSetIssueState(client, o, "open", "issue open"),
|
|
638
|
+
spec: spec("用法:gitee issue open [<repo>] <编号>", "重开 Issue",
|
|
639
|
+
clientOpts(), ISSUE_POS),
|
|
640
|
+
},
|
|
641
|
+
close: {
|
|
642
|
+
run: (client, o) => cmdSetIssueState(client, o, "closed", "issue close"),
|
|
643
|
+
spec: spec("用法:gitee issue close [<repo>] <编号>", "关闭 Issue",
|
|
644
|
+
clientOpts(), ISSUE_POS),
|
|
645
|
+
},
|
|
646
|
+
comment: {
|
|
647
|
+
run: (client, o) => cmdIssueComment(client, o),
|
|
648
|
+
spec: spec("用法:gitee issue comment [<repo>] <编号> -m 内容|-f 文件", "给 Issue 加评论",
|
|
649
|
+
[{ short: "-m", long: "--message", dest: "message", arg: "value", help: "评论内容" },
|
|
650
|
+
{ short: "-f", long: "--file", dest: "file", arg: "value",
|
|
651
|
+
help: "从 UTF-8 文件读评论内容(与 -m 二选一)" },
|
|
652
|
+
...clientOpts()],
|
|
653
|
+
ISSUE_POS),
|
|
654
|
+
},
|
|
655
|
+
};
|
|
656
|
+
|
|
398
657
|
const SUBCOMMANDS = {
|
|
399
658
|
set: {
|
|
400
659
|
run: (opts) => cmdSetConfig(opts),
|
|
@@ -457,6 +716,23 @@ const SUBCOMMANDS = {
|
|
|
457
716
|
[...STATE_OPTS, ...clientOpts()],
|
|
458
717
|
[{ dest: "repo", required: false, help: "仓库名或 owner/repo(默认当前目录同名仓库)" }]),
|
|
459
718
|
},
|
|
719
|
+
issue: {
|
|
720
|
+
run: null, // 动作族:main 里按 argv[1] 分发到 ISSUE_ACTIONS
|
|
721
|
+
actions: ISSUE_ACTIONS,
|
|
722
|
+
spec: null,
|
|
723
|
+
},
|
|
724
|
+
close: {
|
|
725
|
+
run: (client, o) => cmdSetIssueState(client, o, "closed", "close"),
|
|
726
|
+
spec: spec("用法:gitee close [<repo>] <编号>", "关闭 Issue", clientOpts(),
|
|
727
|
+
[{ dest: "repo", required: false, help: "仓库名或 owner/repo(默认当前目录同名仓库)" },
|
|
728
|
+
{ dest: "number", required: false, help: "Issue 编号(可带 #)" }]),
|
|
729
|
+
},
|
|
730
|
+
reopen: {
|
|
731
|
+
run: (client, o) => cmdSetIssueState(client, o, "open", "reopen"),
|
|
732
|
+
spec: spec("用法:gitee reopen [<repo>] <编号>", "重开 Issue", clientOpts(),
|
|
733
|
+
[{ dest: "repo", required: false, help: "仓库名或 owner/repo(默认当前目录同名仓库)" },
|
|
734
|
+
{ dest: "number", required: false, help: "Issue 编号(可带 #)" }]),
|
|
735
|
+
},
|
|
460
736
|
prs: {
|
|
461
737
|
run: (client, o) => cmdPrs(client, o),
|
|
462
738
|
spec: spec("用法:gitee prs [<repo>] [-s 状态] [-n 条数]", "列出 Pull Request",
|
|
@@ -486,6 +762,9 @@ const TOP_HELP = `gitee — Gitee 仓库管理命令行工具
|
|
|
486
762
|
public/private 切换仓库可见性
|
|
487
763
|
delete 删除仓库
|
|
488
764
|
issues / prs 列出 Issue / Pull Request
|
|
765
|
+
issue Issue 操作族:view / create / edit / open / close / comment
|
|
766
|
+
(无动作词时默认 view;顶层 close/reopen 等价 issue close/open)
|
|
767
|
+
close/reopen 关闭 / 重开 Issue
|
|
489
768
|
push 当前目录建仓并推送
|
|
490
769
|
|
|
491
770
|
用 \`gitee <子命令> -h\` 查看各子命令详情。`;
|
|
@@ -508,7 +787,22 @@ async function main() {
|
|
|
508
787
|
}
|
|
509
788
|
if (cmd === "-h") process.exit(EXIT_OK);
|
|
510
789
|
|
|
511
|
-
|
|
790
|
+
// issue 动作族:argv[1] 必须是动作词,切换到对应 spec(剩余 argv 从 2 起解析)
|
|
791
|
+
let spec = def.spec;
|
|
792
|
+
let action = null;
|
|
793
|
+
if (def.actions) {
|
|
794
|
+
if (argv[1] === undefined) {
|
|
795
|
+
console.error(`错误:缺少 issue 动作\n\n${ISSUE_FAMILY_HELP}`);
|
|
796
|
+
process.exit(EXIT_USAGE);
|
|
797
|
+
}
|
|
798
|
+
action = def.actions[argv[1]] || null;
|
|
799
|
+
if (!action) {
|
|
800
|
+
console.error(`错误:未知 issue 动作 ${JSON.stringify(argv[1])}\n\n${ISSUE_FAMILY_HELP}`);
|
|
801
|
+
process.exit(EXIT_USAGE);
|
|
802
|
+
}
|
|
803
|
+
spec = action.spec;
|
|
804
|
+
}
|
|
805
|
+
const { opts } = parse(spec, action ? argv.slice(2) : argv.slice(1));
|
|
512
806
|
if (def.noAuth) {
|
|
513
807
|
process.exit(await def.run(opts));
|
|
514
808
|
}
|
|
@@ -527,7 +821,7 @@ async function main() {
|
|
|
527
821
|
const [timeout] = resolveValue(opts.timeout, cfg.timeout, null, DEFAULT_TIMEOUT);
|
|
528
822
|
const client = new Client(token, api, proxy, timeout);
|
|
529
823
|
try {
|
|
530
|
-
process.exit(await def.run(client, opts));
|
|
824
|
+
process.exit(await (action ? action.run(client, opts) : def.run(client, opts)));
|
|
531
825
|
} catch (e) {
|
|
532
826
|
if (e instanceof GiteeError) {
|
|
533
827
|
console.error(`错误:${e.message}`);
|