git-stack-cli 1.7.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +58 -48
- package/package.json +1 -1
- package/src/app/LocalMergeRebase.tsx +1 -1
- package/src/app/ManualRebase.tsx +12 -7
- package/src/app/PreManualRebase.tsx +35 -27
- package/src/command.ts +7 -0
- package/src/core/github.tsx +32 -29
package/dist/cjs/index.cjs
CHANGED
|
@@ -27273,8 +27273,6 @@ const RE$1 = {
|
|
|
27273
27273
|
group_title: new RegExp(TEMPLATE$1.group_title("(?<title>[^\\n^\\r]+)"), "i"),
|
|
27274
27274
|
};
|
|
27275
27275
|
|
|
27276
|
-
// prettier-ignore
|
|
27277
|
-
const JSON_FIELDS = "--json number,state,baseRefName,headRefName,commits,title,body,url";
|
|
27278
27276
|
async function pr_list() {
|
|
27279
27277
|
const state = Store.getState();
|
|
27280
27278
|
const actions = state.actions;
|
|
@@ -27282,13 +27280,7 @@ async function pr_list() {
|
|
|
27282
27280
|
const repo_path = state.repo_path;
|
|
27283
27281
|
invariant(username, "username must exist");
|
|
27284
27282
|
invariant(repo_path, "repo_path must exist");
|
|
27285
|
-
const
|
|
27286
|
-
ignoreExitCode: true,
|
|
27287
|
-
});
|
|
27288
|
-
if (cli_result.code !== 0) {
|
|
27289
|
-
handle_error(cli_result.output);
|
|
27290
|
-
}
|
|
27291
|
-
const result_pr_list = JSON.parse(cli_result.stdout);
|
|
27283
|
+
const result_pr_list = await gh_json(`pr list --repo ${repo_path} --author ${username} --state open ${JSON_FIELDS}`);
|
|
27292
27284
|
if (actions.isDebug()) {
|
|
27293
27285
|
actions.output(reactExports.createElement(Text, { dimColor: true },
|
|
27294
27286
|
reactExports.createElement(Text, null, "Github cache "),
|
|
@@ -27332,14 +27324,7 @@ async function pr_status(branch) {
|
|
|
27332
27324
|
reactExports.createElement(Text, null, " "),
|
|
27333
27325
|
reactExports.createElement(Text, { dimColor: true }, branch)));
|
|
27334
27326
|
}
|
|
27335
|
-
const
|
|
27336
|
-
ignoreExitCode: true,
|
|
27337
|
-
});
|
|
27338
|
-
if (cli_result.code !== 0) {
|
|
27339
|
-
// handle_error(cli_result.output);
|
|
27340
|
-
return null;
|
|
27341
|
-
}
|
|
27342
|
-
const pr = JSON.parse(cli_result.stdout);
|
|
27327
|
+
const pr = await gh_json(`pr view ${branch} --repo ${repo_path} ${JSON_FIELDS}`);
|
|
27343
27328
|
actions.set((state) => {
|
|
27344
27329
|
state.pr[pr.headRefName] = pr;
|
|
27345
27330
|
});
|
|
@@ -27347,7 +27332,11 @@ async function pr_status(branch) {
|
|
|
27347
27332
|
}
|
|
27348
27333
|
async function pr_create(args) {
|
|
27349
27334
|
const title = safe_quote(args.title);
|
|
27350
|
-
|
|
27335
|
+
let command = `gh pr create --fill --head ${args.branch} --base ${args.base} --title="${title}" --body="${args.body}"`;
|
|
27336
|
+
if (args.draft) {
|
|
27337
|
+
command += " --draft";
|
|
27338
|
+
}
|
|
27339
|
+
const cli_result = await cli(command);
|
|
27351
27340
|
if (cli_result.code !== 0) {
|
|
27352
27341
|
handle_error(cli_result.output);
|
|
27353
27342
|
return null;
|
|
@@ -27362,6 +27351,22 @@ async function pr_edit(args) {
|
|
|
27362
27351
|
handle_error(cli_result.output);
|
|
27363
27352
|
}
|
|
27364
27353
|
}
|
|
27354
|
+
// prettier-ignore
|
|
27355
|
+
const JSON_FIELDS = "--json number,state,baseRefName,headRefName,commits,title,body,url";
|
|
27356
|
+
// consistent handle gh cli commands returning json
|
|
27357
|
+
// redirect to tmp file to avoid scrollback overflow causing scrollback to be cleared
|
|
27358
|
+
async function gh_json(command) {
|
|
27359
|
+
const tmp_pr_json = path.join(os.tmpdir(), "git-stack-gh.json");
|
|
27360
|
+
const options = { ignoreExitCode: true };
|
|
27361
|
+
const cli_result = await cli(`gh ${command} > ${tmp_pr_json}`, options);
|
|
27362
|
+
if (cli_result.code !== 0) {
|
|
27363
|
+
handle_error(cli_result.output);
|
|
27364
|
+
}
|
|
27365
|
+
// read from file
|
|
27366
|
+
const json_str = fs.readFileSync(tmp_pr_json, "utf-8");
|
|
27367
|
+
const json = JSON.parse(json_str);
|
|
27368
|
+
return json;
|
|
27369
|
+
}
|
|
27365
27370
|
function handle_error(output) {
|
|
27366
27371
|
const state = Store.getState();
|
|
27367
27372
|
const actions = state.actions;
|
|
@@ -27654,7 +27659,7 @@ async function run$4() {
|
|
|
27654
27659
|
process.once("SIGINT", handle_exit);
|
|
27655
27660
|
const temp_branch_name = `${branch_name}_${short_id()}`;
|
|
27656
27661
|
try {
|
|
27657
|
-
actions.debug(`commit_range=${JSON.stringify(commit_range, null, 2)}`);
|
|
27662
|
+
// actions.debug(`commit_range=${JSON.stringify(commit_range, null, 2)}`);
|
|
27658
27663
|
// must perform rebase from repo root for applying git patch
|
|
27659
27664
|
process.chdir(repo_root);
|
|
27660
27665
|
await cli(`pwd`);
|
|
@@ -27972,7 +27977,7 @@ async function run$3() {
|
|
|
27972
27977
|
}
|
|
27973
27978
|
actions.debug(`rebase_merge_base = ${rebase_merge_base}`);
|
|
27974
27979
|
actions.debug(`rebase_group_index = ${rebase_group_index}`);
|
|
27975
|
-
actions.debug(`commit_range=${JSON.stringify(commit_range, null, 2)}`);
|
|
27980
|
+
// actions.debug(`commit_range=${JSON.stringify(commit_range, null, 2)}`);
|
|
27976
27981
|
try {
|
|
27977
27982
|
// must perform rebase from repo root for applying git patch
|
|
27978
27983
|
process.chdir(repo_root);
|
|
@@ -28058,7 +28063,7 @@ echo "$GIT_REVISE_TODO" > "$git_revise_todo_path"
|
|
|
28058
28063
|
`GIT_REVISE_TODO="${git_revise_todo}"`,
|
|
28059
28064
|
`git`,
|
|
28060
28065
|
`revise --edit -i ${rebase_merge_base}`,
|
|
28061
|
-
]);
|
|
28066
|
+
], { stdio: ["ignore", "ignore", "ignore"] });
|
|
28062
28067
|
// early return since we do not need to sync
|
|
28063
28068
|
if (!argv.sync) {
|
|
28064
28069
|
return;
|
|
@@ -28175,6 +28180,7 @@ echo "$GIT_REVISE_TODO" > "$git_revise_todo_path"
|
|
|
28175
28180
|
base: group.base,
|
|
28176
28181
|
title: group.title,
|
|
28177
28182
|
body: DEFAULT_PR_BODY,
|
|
28183
|
+
draft: argv.draft,
|
|
28178
28184
|
});
|
|
28179
28185
|
if (!pr_url) {
|
|
28180
28186
|
throw new Error("unable to create pr");
|
|
@@ -28487,25 +28493,26 @@ async function run$1() {
|
|
|
28487
28493
|
state.step = "manual-rebase";
|
|
28488
28494
|
});
|
|
28489
28495
|
}
|
|
28490
|
-
|
|
28491
|
-
let pr_templates = [];
|
|
28492
|
-
if (fs.existsSync(template_pr_template(repo_root))) {
|
|
28493
|
-
pr_templates = fs.readdirSync(template_pr_template(repo_root));
|
|
28494
|
-
}
|
|
28496
|
+
let pr_template_body = null;
|
|
28495
28497
|
// look for pull request template
|
|
28496
28498
|
// https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository
|
|
28497
28499
|
// ./.github/pull_request_template.md
|
|
28498
28500
|
// ./pull_request_template.md
|
|
28499
28501
|
// ./docs/pull_request_template.md
|
|
28500
|
-
|
|
28501
|
-
|
|
28502
|
-
|
|
28503
|
-
|
|
28504
|
-
|
|
28505
|
-
|
|
28502
|
+
for (const key of PR_TEMPLATE_KEY_LIST) {
|
|
28503
|
+
const pr_template_fn = PR_TEMPLATE[key];
|
|
28504
|
+
if (fs.existsSync(pr_template_fn(repo_root))) {
|
|
28505
|
+
pr_template_body = fs.readFileSync(pr_template_fn(repo_root), "utf-8");
|
|
28506
|
+
actions.output(reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, { color: colors.yellow }), message: "Using PR template {pr_filepath}", values: {
|
|
28507
|
+
pr_filepath: reactExports.createElement(Brackets, null, pr_template_fn("")),
|
|
28508
|
+
} }));
|
|
28509
|
+
break;
|
|
28510
|
+
}
|
|
28506
28511
|
}
|
|
28507
|
-
|
|
28508
|
-
|
|
28512
|
+
// ./.github/PULL_REQUEST_TEMPLATE/*.md
|
|
28513
|
+
let pr_templates = [];
|
|
28514
|
+
if (fs.existsSync(PR_TEMPLATE.TemplateDir(repo_root))) {
|
|
28515
|
+
pr_templates = fs.readdirSync(PR_TEMPLATE.TemplateDir(repo_root));
|
|
28509
28516
|
}
|
|
28510
28517
|
// check if repo has multiple pr templates
|
|
28511
28518
|
actions.set((state) => {
|
|
@@ -28514,24 +28521,21 @@ async function run$1() {
|
|
|
28514
28521
|
if (pr_templates.length > 0) {
|
|
28515
28522
|
actions.output(reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, { color: colors.yellow }), message: "{count} queryable templates found under {dir}, but not supported.", values: {
|
|
28516
28523
|
count: (reactExports.createElement(Text, { color: colors.blue }, pr_templates.length)),
|
|
28517
|
-
dir: reactExports.createElement(Brackets, null,
|
|
28524
|
+
dir: reactExports.createElement(Brackets, null, PR_TEMPLATE.TemplateDir("")),
|
|
28518
28525
|
} }));
|
|
28519
28526
|
}
|
|
28520
28527
|
state.step = "manual-rebase";
|
|
28521
28528
|
});
|
|
28522
28529
|
}
|
|
28523
|
-
|
|
28524
|
-
|
|
28525
|
-
|
|
28526
|
-
|
|
28527
|
-
|
|
28528
|
-
|
|
28529
|
-
|
|
28530
|
-
|
|
28531
|
-
|
|
28532
|
-
function template_pr_template(repo_root) {
|
|
28533
|
-
return path.join(repo_root, ".github", "PULL_REQUEST_TEMPLATE");
|
|
28534
|
-
}
|
|
28530
|
+
// prettier-ignore
|
|
28531
|
+
const PR_TEMPLATE = Object.freeze({
|
|
28532
|
+
Github: (root) => path.join(root, ".github", "pull_request_template.md"),
|
|
28533
|
+
Root: (root) => path.join(root, "pull_request_template.md"),
|
|
28534
|
+
Docs: (root) => path.join(root, "docs", "pull_request_template.md"),
|
|
28535
|
+
TemplateDir: (root) => path.join(root, ".github", "PULL_REQUEST_TEMPLATE"),
|
|
28536
|
+
});
|
|
28537
|
+
// prettier-ignore
|
|
28538
|
+
const PR_TEMPLATE_KEY_LIST = Object.keys(PR_TEMPLATE);
|
|
28535
28539
|
|
|
28536
28540
|
function PreSelectCommitRanges() {
|
|
28537
28541
|
const actions = Store.useActions();
|
|
@@ -34517,6 +34521,12 @@ async function command() {
|
|
|
34517
34521
|
type: "string",
|
|
34518
34522
|
alias: ["b"],
|
|
34519
34523
|
description: 'Set the master branch name, defaults to "master" (or "main" if "master" is not found)',
|
|
34524
|
+
})
|
|
34525
|
+
.option("draft", {
|
|
34526
|
+
type: "boolean",
|
|
34527
|
+
alias: ["d"],
|
|
34528
|
+
default: false,
|
|
34529
|
+
description: "Open all PRs as drafts",
|
|
34520
34530
|
})
|
|
34521
34531
|
.option("write-state-json", {
|
|
34522
34532
|
hidden: true,
|
|
@@ -34541,7 +34551,7 @@ async function command() {
|
|
|
34541
34551
|
.wrap(123)
|
|
34542
34552
|
// disallow unknown options
|
|
34543
34553
|
.strict()
|
|
34544
|
-
.version("1.
|
|
34554
|
+
.version("1.8.1" )
|
|
34545
34555
|
.showHidden("show-hidden", "Show hidden options via `git stack help --show-hidden`")
|
|
34546
34556
|
.help("help", "Show usage via `git stack help`").argv);
|
|
34547
34557
|
}
|
package/package.json
CHANGED
|
@@ -43,7 +43,7 @@ async function run() {
|
|
|
43
43
|
const temp_branch_name = `${branch_name}_${short_id()}`;
|
|
44
44
|
|
|
45
45
|
try {
|
|
46
|
-
actions.debug(`commit_range=${JSON.stringify(commit_range, null, 2)}`);
|
|
46
|
+
// actions.debug(`commit_range=${JSON.stringify(commit_range, null, 2)}`);
|
|
47
47
|
|
|
48
48
|
// must perform rebase from repo root for applying git patch
|
|
49
49
|
process.chdir(repo_root);
|
package/src/app/ManualRebase.tsx
CHANGED
|
@@ -83,7 +83,8 @@ async function run() {
|
|
|
83
83
|
|
|
84
84
|
actions.debug(`rebase_merge_base = ${rebase_merge_base}`);
|
|
85
85
|
actions.debug(`rebase_group_index = ${rebase_group_index}`);
|
|
86
|
-
|
|
86
|
+
|
|
87
|
+
// actions.debug(`commit_range=${JSON.stringify(commit_range, null, 2)}`);
|
|
87
88
|
|
|
88
89
|
try {
|
|
89
90
|
// must perform rebase from repo root for applying git patch
|
|
@@ -153,12 +154,15 @@ async function run() {
|
|
|
153
154
|
|
|
154
155
|
// execute cli with temporary git sequence editor script
|
|
155
156
|
// revise from merge base to pick correct commits
|
|
156
|
-
await cli(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
157
|
+
await cli(
|
|
158
|
+
[
|
|
159
|
+
`GIT_EDITOR="${tmp_git_sequence_editor_path}"`,
|
|
160
|
+
`GIT_REVISE_TODO="${git_revise_todo}"`,
|
|
161
|
+
`git`,
|
|
162
|
+
`revise --edit -i ${rebase_merge_base}`,
|
|
163
|
+
],
|
|
164
|
+
{ stdio: ["ignore", "ignore", "ignore"] }
|
|
165
|
+
);
|
|
162
166
|
|
|
163
167
|
// early return since we do not need to sync
|
|
164
168
|
if (!argv.sync) {
|
|
@@ -334,6 +338,7 @@ async function run() {
|
|
|
334
338
|
base: group.base,
|
|
335
339
|
title: group.title,
|
|
336
340
|
body: DEFAULT_PR_BODY,
|
|
341
|
+
draft: argv.draft,
|
|
337
342
|
});
|
|
338
343
|
|
|
339
344
|
if (!pr_url) {
|
|
@@ -31,24 +31,37 @@ async function run() {
|
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
let pr_templates: Array<string> = [];
|
|
36
|
-
if (fs.existsSync(template_pr_template(repo_root))) {
|
|
37
|
-
pr_templates = fs.readdirSync(template_pr_template(repo_root));
|
|
38
|
-
}
|
|
34
|
+
let pr_template_body: null | string = null;
|
|
39
35
|
|
|
40
36
|
// look for pull request template
|
|
41
37
|
// https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository
|
|
42
38
|
// ./.github/pull_request_template.md
|
|
43
39
|
// ./pull_request_template.md
|
|
44
40
|
// ./docs/pull_request_template.md
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
for (const key of PR_TEMPLATE_KEY_LIST) {
|
|
42
|
+
const pr_template_fn = PR_TEMPLATE[key as keyof typeof PR_TEMPLATE];
|
|
43
|
+
|
|
44
|
+
if (fs.existsSync(pr_template_fn(repo_root))) {
|
|
45
|
+
pr_template_body = fs.readFileSync(pr_template_fn(repo_root), "utf-8");
|
|
46
|
+
|
|
47
|
+
actions.output(
|
|
48
|
+
<FormatText
|
|
49
|
+
wrapper={<Ink.Text color={colors.yellow} />}
|
|
50
|
+
message="Using PR template {pr_filepath}"
|
|
51
|
+
values={{
|
|
52
|
+
pr_filepath: <Brackets>{pr_template_fn("")}</Brackets>,
|
|
53
|
+
}}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ./.github/PULL_REQUEST_TEMPLATE/*.md
|
|
62
|
+
let pr_templates: Array<string> = [];
|
|
63
|
+
if (fs.existsSync(PR_TEMPLATE.TemplateDir(repo_root))) {
|
|
64
|
+
pr_templates = fs.readdirSync(PR_TEMPLATE.TemplateDir(repo_root));
|
|
52
65
|
}
|
|
53
66
|
|
|
54
67
|
// check if repo has multiple pr templates
|
|
@@ -65,7 +78,7 @@ async function run() {
|
|
|
65
78
|
count: (
|
|
66
79
|
<Ink.Text color={colors.blue}>{pr_templates.length}</Ink.Text>
|
|
67
80
|
),
|
|
68
|
-
dir: <Brackets>{
|
|
81
|
+
dir: <Brackets>{PR_TEMPLATE.TemplateDir("")}</Brackets>,
|
|
69
82
|
}}
|
|
70
83
|
/>
|
|
71
84
|
);
|
|
@@ -75,18 +88,13 @@ async function run() {
|
|
|
75
88
|
});
|
|
76
89
|
}
|
|
77
90
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
91
|
+
// prettier-ignore
|
|
92
|
+
const PR_TEMPLATE = Object.freeze({
|
|
93
|
+
Github: (root: string) => path.join(root, ".github", "pull_request_template.md"),
|
|
94
|
+
Root: (root: string) => path.join(root, "pull_request_template.md"),
|
|
95
|
+
Docs: (root: string) => path.join(root, "docs", "pull_request_template.md"),
|
|
96
|
+
TemplateDir: (root: string) => path.join(root, ".github", "PULL_REQUEST_TEMPLATE"),
|
|
97
|
+
});
|
|
85
98
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function template_pr_template(repo_root: string) {
|
|
91
|
-
return path.join(repo_root, ".github", "PULL_REQUEST_TEMPLATE");
|
|
92
|
-
}
|
|
99
|
+
// prettier-ignore
|
|
100
|
+
const PR_TEMPLATE_KEY_LIST = Object.keys(PR_TEMPLATE) as Array<keyof typeof PR_TEMPLATE>;
|
package/src/command.ts
CHANGED
|
@@ -71,6 +71,13 @@ export async function command() {
|
|
|
71
71
|
'Set the master branch name, defaults to "master" (or "main" if "master" is not found)',
|
|
72
72
|
})
|
|
73
73
|
|
|
74
|
+
.option("draft", {
|
|
75
|
+
type: "boolean",
|
|
76
|
+
alias: ["d"],
|
|
77
|
+
default: false,
|
|
78
|
+
description: "Open all PRs as drafts",
|
|
79
|
+
})
|
|
80
|
+
|
|
74
81
|
.option("write-state-json", {
|
|
75
82
|
hidden: true,
|
|
76
83
|
type: "boolean",
|
package/src/core/github.tsx
CHANGED
|
@@ -13,9 +13,6 @@ import { colors } from "~/core/colors";
|
|
|
13
13
|
import { invariant } from "~/core/invariant";
|
|
14
14
|
import { safe_quote } from "~/core/safe_quote";
|
|
15
15
|
|
|
16
|
-
// prettier-ignore
|
|
17
|
-
const JSON_FIELDS = "--json number,state,baseRefName,headRefName,commits,title,body,url";
|
|
18
|
-
|
|
19
16
|
export async function pr_list(): Promise<Array<PullRequest>> {
|
|
20
17
|
const state = Store.getState();
|
|
21
18
|
const actions = state.actions;
|
|
@@ -25,19 +22,10 @@ export async function pr_list(): Promise<Array<PullRequest>> {
|
|
|
25
22
|
invariant(username, "username must exist");
|
|
26
23
|
invariant(repo_path, "repo_path must exist");
|
|
27
24
|
|
|
28
|
-
const
|
|
29
|
-
`
|
|
30
|
-
{
|
|
31
|
-
ignoreExitCode: true,
|
|
32
|
-
}
|
|
25
|
+
const result_pr_list: Array<PullRequest> = await gh_json(
|
|
26
|
+
`pr list --repo ${repo_path} --author ${username} --state open ${JSON_FIELDS}`
|
|
33
27
|
);
|
|
34
28
|
|
|
35
|
-
if (cli_result.code !== 0) {
|
|
36
|
-
handle_error(cli_result.output);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const result_pr_list: Array<PullRequest> = JSON.parse(cli_result.stdout);
|
|
40
|
-
|
|
41
29
|
if (actions.isDebug()) {
|
|
42
30
|
actions.output(
|
|
43
31
|
<Ink.Text dimColor>
|
|
@@ -105,20 +93,10 @@ export async function pr_status(branch: string): Promise<null | PullRequest> {
|
|
|
105
93
|
);
|
|
106
94
|
}
|
|
107
95
|
|
|
108
|
-
const
|
|
109
|
-
`
|
|
110
|
-
{
|
|
111
|
-
ignoreExitCode: true,
|
|
112
|
-
}
|
|
96
|
+
const pr: PullRequest = await gh_json(
|
|
97
|
+
`pr view ${branch} --repo ${repo_path} ${JSON_FIELDS}`
|
|
113
98
|
);
|
|
114
99
|
|
|
115
|
-
if (cli_result.code !== 0) {
|
|
116
|
-
// handle_error(cli_result.output);
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const pr: PullRequest = JSON.parse(cli_result.stdout);
|
|
121
|
-
|
|
122
100
|
actions.set((state) => {
|
|
123
101
|
state.pr[pr.headRefName] = pr;
|
|
124
102
|
});
|
|
@@ -131,14 +109,18 @@ type CreatePullRequestArgs = {
|
|
|
131
109
|
base: string;
|
|
132
110
|
title: string;
|
|
133
111
|
body: string;
|
|
112
|
+
draft: boolean;
|
|
134
113
|
};
|
|
135
114
|
|
|
136
115
|
export async function pr_create(args: CreatePullRequestArgs) {
|
|
137
116
|
const title = safe_quote(args.title);
|
|
117
|
+
let command = `gh pr create --fill --head ${args.branch} --base ${args.base} --title="${title}" --body="${args.body}"`;
|
|
138
118
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
119
|
+
if (args.draft) {
|
|
120
|
+
command += " --draft";
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const cli_result = await cli(command);
|
|
142
124
|
|
|
143
125
|
if (cli_result.code !== 0) {
|
|
144
126
|
handle_error(cli_result.output);
|
|
@@ -165,6 +147,27 @@ export async function pr_edit(args: EditPullRequestArgs) {
|
|
|
165
147
|
}
|
|
166
148
|
}
|
|
167
149
|
|
|
150
|
+
// prettier-ignore
|
|
151
|
+
const JSON_FIELDS = "--json number,state,baseRefName,headRefName,commits,title,body,url";
|
|
152
|
+
|
|
153
|
+
// consistent handle gh cli commands returning json
|
|
154
|
+
// redirect to tmp file to avoid scrollback overflow causing scrollback to be cleared
|
|
155
|
+
async function gh_json(command: string) {
|
|
156
|
+
const tmp_pr_json = path.join(os.tmpdir(), "git-stack-gh.json");
|
|
157
|
+
|
|
158
|
+
const options = { ignoreExitCode: true };
|
|
159
|
+
const cli_result = await cli(`gh ${command} > ${tmp_pr_json}`, options);
|
|
160
|
+
|
|
161
|
+
if (cli_result.code !== 0) {
|
|
162
|
+
handle_error(cli_result.output);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// read from file
|
|
166
|
+
const json_str = fs.readFileSync(tmp_pr_json, "utf-8");
|
|
167
|
+
const json = JSON.parse(json_str);
|
|
168
|
+
return json;
|
|
169
|
+
}
|
|
170
|
+
|
|
168
171
|
function handle_error(output: string): never {
|
|
169
172
|
const state = Store.getState();
|
|
170
173
|
const actions = state.actions;
|