git-stack-cli 1.11.7 → 1.13.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 +11 -1
- package/dist/cjs/index.cjs +204 -203
- package/package.json +1 -1
- package/src/app/AutoUpdate.tsx +5 -3
- package/src/app/CherryPickCheck.tsx +4 -4
- package/src/app/Debug.tsx +12 -9
- package/src/app/DependencyCheck.tsx +0 -6
- package/src/app/ManualRebase.tsx +134 -180
- package/src/app/PreManualRebase.tsx +6 -5
- package/src/app/RebaseCheck.tsx +3 -3
- package/src/command.ts +0 -16
- package/src/commands/Rebase.tsx +2 -15
- package/src/core/GitReviseTodo.test.ts +16 -0
- package/src/core/GitReviseTodo.ts +3 -3
- package/src/core/github.tsx +65 -10
- package/src/core/read_json.ts +3 -3
- package/src/core/safe_exists.ts +10 -0
- package/src/core/safe_rm.ts +10 -0
|
@@ -82,6 +82,8 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
82
82
|
id: "AAWsYx1UU",
|
|
83
83
|
title: "banana",
|
|
84
84
|
pr: {
|
|
85
|
+
id: "PR_kwDOKjvFM85ghvAH",
|
|
86
|
+
isDraft: false,
|
|
85
87
|
baseRefName: "master",
|
|
86
88
|
body: "adsf\r\n\r\n#### git stack\n- ⏳ `2` https://github.com/magus/git-multi-diff-playground/pull/47\n- 👉 `1` https://github.com/magus/git-multi-diff-playground/pull/43",
|
|
87
89
|
commits: [
|
|
@@ -123,6 +125,8 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
123
125
|
id: "E63ytp5dj",
|
|
124
126
|
title: "lemon color",
|
|
125
127
|
pr: {
|
|
128
|
+
id: "PR_kwDOKjvFM85gwTkx",
|
|
129
|
+
isDraft: false,
|
|
126
130
|
baseRefName: "AAWsYx1UU",
|
|
127
131
|
body: "\r\n\r\n#### git stack\n- 👉 `3` https://github.com/magus/git-multi-diff-playground/pull/47\n- ⏳ `2` https://github.com/magus/git-multi-diff-playground/pull/43\n- ✅ `1`\n https://github.com/magus/git-multi-diff-playground/pull/42",
|
|
128
132
|
commits: [
|
|
@@ -251,6 +255,8 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
251
255
|
],
|
|
252
256
|
pr_lookup: {
|
|
253
257
|
AAWsYx1UU: {
|
|
258
|
+
id: "PR_kwDOKjvFM85ghvAH",
|
|
259
|
+
isDraft: false,
|
|
254
260
|
baseRefName: "master",
|
|
255
261
|
body: "adsf\r\n\r\n#### git stack\n- ⏳ `2` https://github.com/magus/git-multi-diff-playground/pull/47\n- 👉 `1` https://github.com/magus/git-multi-diff-playground/pull/43",
|
|
256
262
|
commits: [
|
|
@@ -277,6 +283,8 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
277
283
|
url: "https://github.com/magus/git-multi-diff-playground/pull/43",
|
|
278
284
|
},
|
|
279
285
|
E63ytp5dj: {
|
|
286
|
+
id: "PR_kwDOKjvFM85gwTkx",
|
|
287
|
+
isDraft: false,
|
|
280
288
|
baseRefName: "AAWsYx1UU",
|
|
281
289
|
body: "\r\n\r\n#### git stack\n- 👉 `3` https://github.com/magus/git-multi-diff-playground/pull/47\n- ⏳ `2` https://github.com/magus/git-multi-diff-playground/pull/43\n- ✅ `1`\n https://github.com/magus/git-multi-diff-playground/pull/42",
|
|
282
290
|
commits: [
|
|
@@ -343,6 +351,8 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
343
351
|
id: "AAWsYx1UU",
|
|
344
352
|
title: "banana",
|
|
345
353
|
pr: {
|
|
354
|
+
id: "PR_kwDOKjvFM85ghvAH",
|
|
355
|
+
isDraft: false,
|
|
346
356
|
baseRefName: "master",
|
|
347
357
|
body: "adsf\r\n\r\n#### git stack\n- ⏳ `2` https://github.com/magus/git-multi-diff-playground/pull/47\n- 👉 `1` https://github.com/magus/git-multi-diff-playground/pull/43",
|
|
348
358
|
commits: [
|
|
@@ -384,6 +394,8 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
384
394
|
id: "E63ytp5dj",
|
|
385
395
|
title: "lemon color",
|
|
386
396
|
pr: {
|
|
397
|
+
id: "PR_kwDOKjvFM85gwTkx",
|
|
398
|
+
isDraft: false,
|
|
387
399
|
baseRefName: "AAWsYx1UU",
|
|
388
400
|
body: "\r\n\r\n#### git stack\n- 👉 `3` https://github.com/magus/git-multi-diff-playground/pull/47\n- ⏳ `2` https://github.com/magus/git-multi-diff-playground/pull/43\n- ✅ `1`\n https://github.com/magus/git-multi-diff-playground/pull/42",
|
|
389
401
|
commits: [
|
|
@@ -521,6 +533,8 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
521
533
|
],
|
|
522
534
|
pr_lookup: {
|
|
523
535
|
AAWsYx1UU: {
|
|
536
|
+
id: "PR_kwDOKjvFM85ghvAH",
|
|
537
|
+
isDraft: false,
|
|
524
538
|
baseRefName: "master",
|
|
525
539
|
body: "adsf\r\n\r\n#### git stack\n- ⏳ `2` https://github.com/magus/git-multi-diff-playground/pull/47\n- 👉 `1` https://github.com/magus/git-multi-diff-playground/pull/43",
|
|
526
540
|
commits: [
|
|
@@ -547,6 +561,8 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
547
561
|
url: "https://github.com/magus/git-multi-diff-playground/pull/43",
|
|
548
562
|
},
|
|
549
563
|
E63ytp5dj: {
|
|
564
|
+
id: "PR_kwDOKjvFM85gwTkx",
|
|
565
|
+
isDraft: false,
|
|
550
566
|
baseRefName: "AAWsYx1UU",
|
|
551
567
|
body: "\r\n\r\n#### git stack\n- 👉 `3` https://github.com/magus/git-multi-diff-playground/pull/47\n- ⏳ `2` https://github.com/magus/git-multi-diff-playground/pull/43\n- ✅ `1`\n https://github.com/magus/git-multi-diff-playground/pull/42",
|
|
552
568
|
commits: [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
|
|
@@ -120,10 +120,10 @@ GitReviseTodo.execute = async function grt_execute(args: ExecuteArgs) {
|
|
|
120
120
|
const GIT_SEQUENCE_EDITOR_SCRIPT = `process.env.GIT_SEQUENCE_EDITOR_SCRIPT`;
|
|
121
121
|
|
|
122
122
|
// write script to temporary path
|
|
123
|
-
fs.
|
|
123
|
+
await fs.writeFile(tmp_git_sequence_editor_path, GIT_SEQUENCE_EDITOR_SCRIPT);
|
|
124
124
|
|
|
125
125
|
// ensure script is executable
|
|
126
|
-
fs.
|
|
126
|
+
await fs.chmod(tmp_git_sequence_editor_path, "755");
|
|
127
127
|
|
|
128
128
|
const git_revise_todo = GitReviseTodo(args);
|
|
129
129
|
|
package/src/core/github.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
|
|
3
|
-
import fs from "node:fs";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
|
|
@@ -12,6 +12,7 @@ import { cli } from "~/core/cli";
|
|
|
12
12
|
import { colors } from "~/core/colors";
|
|
13
13
|
import { invariant } from "~/core/invariant";
|
|
14
14
|
import { safe_quote } from "~/core/safe_quote";
|
|
15
|
+
import { safe_rm } from "~/core/safe_rm";
|
|
15
16
|
|
|
16
17
|
export async function pr_list(): Promise<Array<PullRequest>> {
|
|
17
18
|
const state = Store.getState();
|
|
@@ -148,7 +149,8 @@ export async function pr_edit(args: EditPullRequestArgs) {
|
|
|
148
149
|
const command_parts = [`gh pr edit ${args.branch} --base ${args.base}`];
|
|
149
150
|
|
|
150
151
|
if (args.body) {
|
|
151
|
-
|
|
152
|
+
const body_file = await write_body_file(args);
|
|
153
|
+
command_parts.push(`--body-file="${body_file}"`);
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
const command = command_parts.join(" ");
|
|
@@ -160,8 +162,56 @@ export async function pr_edit(args: EditPullRequestArgs) {
|
|
|
160
162
|
}
|
|
161
163
|
}
|
|
162
164
|
|
|
165
|
+
type DraftPullRequestArgs = {
|
|
166
|
+
branch: string;
|
|
167
|
+
draft: boolean;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export async function pr_draft(args: DraftPullRequestArgs) {
|
|
171
|
+
// https://cli.github.com/manual/gh_api
|
|
172
|
+
// https://docs.github.com/en/graphql/reference/mutations#convertpullrequesttodraft
|
|
173
|
+
// https://docs.github.com/en/graphql/reference/mutations#markpullrequestreadyforreview
|
|
174
|
+
|
|
175
|
+
const mutation_name = args.draft
|
|
176
|
+
? "convertPullRequestToDraft"
|
|
177
|
+
: "markPullRequestReadyForReview";
|
|
178
|
+
|
|
179
|
+
let query = `
|
|
180
|
+
mutation($id: ID!) {
|
|
181
|
+
${mutation_name}(input: { pullRequestId: $id }) {
|
|
182
|
+
pullRequest {
|
|
183
|
+
id
|
|
184
|
+
number
|
|
185
|
+
isDraft
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
`;
|
|
190
|
+
|
|
191
|
+
query = query.replace(/\n/g, " ");
|
|
192
|
+
query = query.replace(/\s+/g, " ");
|
|
193
|
+
query = query.trim();
|
|
194
|
+
|
|
195
|
+
// lookup id from pr cache using args.branch
|
|
196
|
+
const state = Store.getState();
|
|
197
|
+
const cache_pr = state.pr[args.branch];
|
|
198
|
+
invariant(cache_pr, "cache_pr must exist");
|
|
199
|
+
|
|
200
|
+
const command_parts = [
|
|
201
|
+
`gh api graphql -F id="${cache_pr.id}" -f query='${query}'`,
|
|
202
|
+
];
|
|
203
|
+
|
|
204
|
+
const command = command_parts.join(" ");
|
|
205
|
+
|
|
206
|
+
const cli_result = await cli(command);
|
|
207
|
+
|
|
208
|
+
if (cli_result.code !== 0) {
|
|
209
|
+
handle_error(cli_result.output);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
163
213
|
// prettier-ignore
|
|
164
|
-
const JSON_FIELDS = "--json number,state,baseRefName,headRefName,commits,title,body,url";
|
|
214
|
+
const JSON_FIELDS = "--json id,number,state,baseRefName,headRefName,commits,title,body,url,isDraft";
|
|
165
215
|
|
|
166
216
|
// consistent handle gh cli commands returning json
|
|
167
217
|
// redirect to tmp file to avoid scrollback overflow causing scrollback to be cleared
|
|
@@ -176,7 +226,7 @@ async function gh_json<T>(command: string): Promise<T | Error> {
|
|
|
176
226
|
}
|
|
177
227
|
|
|
178
228
|
// read from file
|
|
179
|
-
const json_str = fs.
|
|
229
|
+
const json_str = await fs.readFile(tmp_pr_json, "utf-8");
|
|
180
230
|
const json = JSON.parse(json_str);
|
|
181
231
|
return json;
|
|
182
232
|
}
|
|
@@ -193,13 +243,16 @@ function handle_error(output: string): never {
|
|
|
193
243
|
}
|
|
194
244
|
|
|
195
245
|
// convert a string to a file for use via github cli `--body-file`
|
|
196
|
-
function
|
|
246
|
+
async function write_body_file(args: EditPullRequestArgs) {
|
|
247
|
+
invariant(args.body, "args.body must exist");
|
|
248
|
+
|
|
197
249
|
const temp_dir = os.tmpdir();
|
|
198
|
-
const temp_path = path.join(temp_dir,
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
fs.
|
|
250
|
+
const temp_path = path.join(temp_dir, `git-stack-body-${args.base}`);
|
|
251
|
+
|
|
252
|
+
await safe_rm(temp_path);
|
|
253
|
+
|
|
254
|
+
await fs.writeFile(temp_path, args.body);
|
|
255
|
+
|
|
203
256
|
return temp_path;
|
|
204
257
|
}
|
|
205
258
|
|
|
@@ -220,6 +273,7 @@ type Commit = {
|
|
|
220
273
|
};
|
|
221
274
|
|
|
222
275
|
export type PullRequest = {
|
|
276
|
+
id: string;
|
|
223
277
|
number: number;
|
|
224
278
|
state: "OPEN" | "MERGED" | "CLOSED";
|
|
225
279
|
baseRefName: string;
|
|
@@ -228,4 +282,5 @@ export type PullRequest = {
|
|
|
228
282
|
title: string;
|
|
229
283
|
body: string;
|
|
230
284
|
url: string;
|
|
285
|
+
isDraft: boolean;
|
|
231
286
|
};
|
package/src/core/read_json.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
2
|
|
|
3
|
-
export function read_json<T = unknown>(path: string): null | T {
|
|
3
|
+
export async function read_json<T = unknown>(path: string): Promise<null | T> {
|
|
4
4
|
try {
|
|
5
|
-
const file_buffer = fs.
|
|
5
|
+
const file_buffer = await fs.readFile(path);
|
|
6
6
|
const json_str = String(file_buffer);
|
|
7
7
|
const json = JSON.parse(json_str);
|
|
8
8
|
return json;
|