git-stack-cli 2.9.2 → 2.9.4
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/js/index.js +78 -78
- package/package.json +1 -1
- package/src/app/App.tsx +13 -8
- package/src/app/DebugOutput.tsx +40 -0
- package/src/app/FetchPullRequests.tsx +40 -0
- package/src/app/GithubApiError.tsx +31 -28
- package/src/app/ManualRebase.tsx +6 -1
- package/src/app/Output.tsx +8 -17
- package/src/app/Store.tsx +31 -72
- package/src/app/SyncGithub.tsx +44 -32
- package/src/app/VerboseDebugInfo.tsx +8 -0
- package/src/core/CommitMetadata.ts +90 -65
- package/src/core/cli.ts +12 -5
- package/src/core/git.ts +1 -1
- package/src/core/github.tsx +135 -46
- package/src/index.tsx +0 -5
- package/src/types/global.d.ts +1 -0
- package/src/app/LogTimestamp.tsx +0 -8
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { Store } from "~/app/Store";
|
|
4
4
|
import * as git from "~/core/git";
|
|
5
5
|
import * as github from "~/core/github";
|
|
6
|
+
import { invariant } from "~/core/invariant";
|
|
6
7
|
|
|
7
8
|
export type CommitRange = Awaited<ReturnType<typeof range>>;
|
|
8
9
|
|
|
@@ -28,16 +29,16 @@ type CommitRangeGroup = {
|
|
|
28
29
|
type CommitGroupMap = { [sha: string]: CommitRangeGroup };
|
|
29
30
|
|
|
30
31
|
export async function range(commit_group_map?: CommitGroupMap) {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const master_branch = Store.getState().master_branch;
|
|
32
|
+
const state = Store.getState();
|
|
33
|
+
const actions = state.actions;
|
|
34
|
+
const argv = state.argv;
|
|
35
|
+
const merge_base = state.merge_base;
|
|
36
|
+
const master_branch = state.master_branch;
|
|
38
37
|
const master_branch_name = master_branch.replace(/^origin\//, "");
|
|
39
38
|
const commit_list = await git.get_commits(`${master_branch}..HEAD`);
|
|
40
39
|
|
|
40
|
+
invariant(merge_base, "merge_base must exist");
|
|
41
|
+
|
|
41
42
|
const pr_lookup: Record<string, void | PullRequest> = {};
|
|
42
43
|
|
|
43
44
|
let invalid = false;
|
|
@@ -127,6 +128,15 @@ export async function range(commit_group_map?: CommitGroupMap) {
|
|
|
127
128
|
const group = group_value_list[i];
|
|
128
129
|
const previous_group: undefined | CommitGroup = group_value_list[i - 1];
|
|
129
130
|
|
|
131
|
+
// actions.json({ group });
|
|
132
|
+
actions.debug(`title=${group.title}`);
|
|
133
|
+
actions.debug(` id=${group.id}`);
|
|
134
|
+
actions.debug(` master_base=${group.master_base}`);
|
|
135
|
+
|
|
136
|
+
// special case
|
|
137
|
+
// boundary between normal commits and master commits
|
|
138
|
+
const MASTER_BASE_BOUNDARY = !group.master_base && previous_group && previous_group.master_base;
|
|
139
|
+
|
|
130
140
|
if (group.id !== UNASSIGNED) {
|
|
131
141
|
let pr_result = pr_lookup[group.id];
|
|
132
142
|
|
|
@@ -147,9 +157,8 @@ export async function range(commit_group_map?: CommitGroupMap) {
|
|
|
147
157
|
if (i === 0) {
|
|
148
158
|
group.base = master_branch_name;
|
|
149
159
|
} else {
|
|
150
|
-
|
|
151
|
-
// console.debug(" ", "
|
|
152
|
-
// console.debug(" ", "last_group.id", last_group.id);
|
|
160
|
+
// console.debug(" ", "previous_group", previous_group.pr?.title.substring(0, 40));
|
|
161
|
+
// console.debug(" ", "previous_group.id", previous_group.id);
|
|
153
162
|
|
|
154
163
|
if (group.master_base) {
|
|
155
164
|
// explicitly set base to master when master_base is true
|
|
@@ -157,77 +166,93 @@ export async function range(commit_group_map?: CommitGroupMap) {
|
|
|
157
166
|
} else if (group.id === UNASSIGNED) {
|
|
158
167
|
// null out base when unassigned and after unassigned
|
|
159
168
|
group.base = null;
|
|
160
|
-
} else if (
|
|
169
|
+
} else if (MASTER_BASE_BOUNDARY) {
|
|
170
|
+
// ensure we set its base to `master`
|
|
171
|
+
actions.debug(` MASTER_BASE_BOUNDARY set group.base = ${master_branch_name}`);
|
|
172
|
+
group.base = master_branch_name;
|
|
173
|
+
} else if (previous_group.base === null) {
|
|
161
174
|
// null out base when last group base is null
|
|
162
175
|
group.base = null;
|
|
163
176
|
} else {
|
|
164
|
-
group.base =
|
|
177
|
+
group.base = previous_group.id;
|
|
165
178
|
}
|
|
166
|
-
|
|
167
|
-
// console.debug(" ", "group.base", group.base);
|
|
168
179
|
}
|
|
169
180
|
|
|
170
|
-
|
|
171
|
-
console.debug({ group });
|
|
172
|
-
}
|
|
181
|
+
actions.debug(` base=${group.base}`);
|
|
173
182
|
|
|
174
183
|
if (!group.pr) {
|
|
184
|
+
actions.debug(` group.pr=${group.pr}`);
|
|
175
185
|
group.dirty = true;
|
|
176
186
|
} else {
|
|
177
|
-
|
|
178
|
-
|
|
187
|
+
// actions.json(group.pr);
|
|
188
|
+
actions.debug(` group.pr.state=${group.pr.state}`);
|
|
189
|
+
actions.debug(` group.pr.baseRefName=${group.pr.baseRefName}`);
|
|
190
|
+
|
|
191
|
+
if (group.pr.state === "MERGED" || group.pr.state === "CLOSED") {
|
|
192
|
+
group.dirty = true;
|
|
193
|
+
} else if (group.pr.baseRefName !== group.base) {
|
|
194
|
+
actions.debug(" PR_BASEREF_MISMATCH");
|
|
179
195
|
group.dirty = true;
|
|
180
196
|
} else if (group.master_base) {
|
|
181
|
-
//
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
let diff_github = await github.pr_diff(group.pr.number);
|
|
189
|
-
diff_github = normalize_diff(diff_github);
|
|
190
|
-
|
|
191
|
-
let diff_local = await git.get_diff(group.commits);
|
|
192
|
-
diff_local = normalize_diff(diff_local);
|
|
193
|
-
|
|
194
|
-
if (DEBUG) {
|
|
195
|
-
console.debug({ diff_local, diff_github });
|
|
197
|
+
// first check if merge base has changed
|
|
198
|
+
let branch_compare = await github.pr_compare(group.pr.headRefName);
|
|
199
|
+
if (!(branch_compare instanceof Error)) {
|
|
200
|
+
if (branch_compare.merge_base_commit.sha !== merge_base) {
|
|
201
|
+
actions.debug(" MASTER_BASE_MERGE_BASE_MISMATCH");
|
|
202
|
+
group.dirty = true;
|
|
203
|
+
}
|
|
196
204
|
}
|
|
197
205
|
|
|
198
|
-
//
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
206
|
+
// if still not dirty, check diffs
|
|
207
|
+
if (!group.dirty) {
|
|
208
|
+
actions.debug(" MASTER_BASE_DIFF_COMPARE");
|
|
209
|
+
|
|
210
|
+
// special case
|
|
211
|
+
// master_base groups cannot be compared by commit sha
|
|
212
|
+
// instead compare the literal diff local against origin
|
|
213
|
+
// gh pr diff --color=never 110
|
|
214
|
+
// git --no-pager diff --color=never 00c8fe0~1..00c8fe0
|
|
215
|
+
let diff_github = await github.pr_diff(group.pr.headRefName);
|
|
216
|
+
diff_github = normalize_diff(diff_github);
|
|
217
|
+
|
|
218
|
+
let diff_local = await git.get_diff(group.commits);
|
|
219
|
+
diff_local = normalize_diff(diff_local);
|
|
220
|
+
|
|
221
|
+
// find the first differing character index
|
|
222
|
+
let compare_length = Math.max(diff_github.length, diff_local.length);
|
|
223
|
+
let diff_index = -1;
|
|
224
|
+
for (let c_i = 0; c_i < compare_length; c_i++) {
|
|
225
|
+
if (diff_github[c_i] !== diff_local[c_i]) {
|
|
226
|
+
diff_index = c_i;
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
205
229
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
230
|
+
if (diff_index > -1) {
|
|
231
|
+
actions.debug(" MASTER_BASE_DIFF_MISMATCH");
|
|
232
|
+
group.dirty = true;
|
|
209
233
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
234
|
+
if (argv.verbose) {
|
|
235
|
+
// print preview at diff_index for both strings
|
|
236
|
+
const preview_radius = 30;
|
|
237
|
+
const start_index = Math.max(0, diff_index - preview_radius);
|
|
238
|
+
const end_index = Math.min(compare_length, diff_index + preview_radius);
|
|
215
239
|
|
|
216
|
-
|
|
217
|
-
|
|
240
|
+
diff_github = diff_github.substring(start_index, end_index);
|
|
241
|
+
diff_github = JSON.stringify(diff_github).slice(1, -1);
|
|
218
242
|
|
|
219
|
-
|
|
220
|
-
|
|
243
|
+
diff_local = diff_local.substring(start_index, end_index);
|
|
244
|
+
diff_local = JSON.stringify(diff_local).slice(1, -1);
|
|
221
245
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
246
|
+
let pointer_indent = " ".repeat(diff_index - start_index + 1);
|
|
247
|
+
actions.debug(` ⚠️ git diff mismatch`);
|
|
248
|
+
actions.debug(` ${pointer_indent}⌄`);
|
|
249
|
+
actions.debug(` diff_github …${diff_github}…`);
|
|
250
|
+
actions.debug(` diff_local …${diff_local}…`);
|
|
251
|
+
actions.debug(` ${pointer_indent}⌃`);
|
|
252
|
+
}
|
|
228
253
|
}
|
|
229
254
|
}
|
|
230
|
-
} else if (
|
|
255
|
+
} else if (MASTER_BASE_BOUNDARY) {
|
|
231
256
|
// special case
|
|
232
257
|
// boundary between normal commits and master commits
|
|
233
258
|
|
|
@@ -245,24 +270,23 @@ export async function range(commit_group_map?: CommitGroupMap) {
|
|
|
245
270
|
|
|
246
271
|
// compare all commits against pr commits
|
|
247
272
|
if (group.pr.commits.length !== all_commits.length) {
|
|
248
|
-
|
|
273
|
+
actions.debug(" BOUNDARY_COMMIT_LENGTH_MISMATCH");
|
|
249
274
|
group.dirty = true;
|
|
250
275
|
} else {
|
|
251
|
-
// console.debug("BOUNDARY_COMMIT_SHA_COMPARISON");
|
|
252
276
|
for (let i = 0; i < group.pr.commits.length; i++) {
|
|
253
277
|
const pr_commit = group.pr.commits[i];
|
|
254
278
|
const local_commit = all_commits[i];
|
|
255
279
|
|
|
256
280
|
if (pr_commit.oid !== local_commit.sha) {
|
|
281
|
+
actions.debug(" BOUNDARY_COMMIT_SHA_MISMATCH");
|
|
257
282
|
group.dirty = true;
|
|
258
283
|
}
|
|
259
284
|
}
|
|
260
285
|
}
|
|
261
286
|
} else if (group.pr.commits.length !== group.commits.length) {
|
|
262
|
-
|
|
287
|
+
actions.debug(" COMMIT_LENGTH_MISMATCH");
|
|
263
288
|
group.dirty = true;
|
|
264
289
|
} else {
|
|
265
|
-
// console.debug("COMMIT_SHA_COMPARISON");
|
|
266
290
|
// if we still haven't marked this dirty, check each commit
|
|
267
291
|
// comapre literal commit shas in group
|
|
268
292
|
for (let i = 0; i < group.pr.commits.length; i++) {
|
|
@@ -270,13 +294,14 @@ export async function range(commit_group_map?: CommitGroupMap) {
|
|
|
270
294
|
const local_commit = group.commits[i];
|
|
271
295
|
|
|
272
296
|
if (pr_commit.oid !== local_commit.sha) {
|
|
297
|
+
actions.debug(" COMMIT_SHA_MISMATCH");
|
|
273
298
|
group.dirty = true;
|
|
274
299
|
}
|
|
275
300
|
}
|
|
276
301
|
}
|
|
277
302
|
}
|
|
278
303
|
|
|
279
|
-
|
|
304
|
+
actions.debug(` group.dirty=${group.dirty}`);
|
|
280
305
|
}
|
|
281
306
|
|
|
282
307
|
// reverse group_list to match git log
|
package/src/core/cli.ts
CHANGED
|
@@ -8,6 +8,7 @@ type SpawnOptions = Parameters<typeof child.spawn>[2];
|
|
|
8
8
|
type Options = SpawnOptions & {
|
|
9
9
|
ignoreExitCode?: boolean;
|
|
10
10
|
onOutput?: (data: string) => void;
|
|
11
|
+
quiet?: boolean;
|
|
11
12
|
};
|
|
12
13
|
|
|
13
14
|
type Return = {
|
|
@@ -45,13 +46,15 @@ export async function cli(
|
|
|
45
46
|
|
|
46
47
|
const id = `${++i}-${command}`;
|
|
47
48
|
state.actions.debug(log.start(command));
|
|
48
|
-
state.actions.
|
|
49
|
+
state.actions.debug_pending(id, log.pending(command));
|
|
49
50
|
|
|
50
51
|
const timer = Timer();
|
|
51
52
|
|
|
52
53
|
function write_output(value: string) {
|
|
53
54
|
output += value;
|
|
54
|
-
|
|
55
|
+
if (!options.quiet) {
|
|
56
|
+
state.actions.debug_pending(id, value);
|
|
57
|
+
}
|
|
55
58
|
options.onOutput?.(value);
|
|
56
59
|
}
|
|
57
60
|
|
|
@@ -79,9 +82,11 @@ export async function cli(
|
|
|
79
82
|
duration,
|
|
80
83
|
};
|
|
81
84
|
|
|
82
|
-
state.actions.
|
|
85
|
+
state.actions.debug_pending_end(id);
|
|
83
86
|
state.actions.debug(log.end(result));
|
|
84
|
-
|
|
87
|
+
if (!options.quiet) {
|
|
88
|
+
state.actions.debug(log.output(result));
|
|
89
|
+
}
|
|
85
90
|
|
|
86
91
|
if (!options.ignoreExitCode && result.code !== 0) {
|
|
87
92
|
state.actions.debug(log.non_zero_exit(result));
|
|
@@ -133,7 +138,9 @@ cli.sync = function cli_sync(
|
|
|
133
138
|
};
|
|
134
139
|
|
|
135
140
|
state.actions.debug(log.end(result));
|
|
136
|
-
|
|
141
|
+
if (!options.quiet) {
|
|
142
|
+
state.actions.debug(log.output(result));
|
|
143
|
+
}
|
|
137
144
|
|
|
138
145
|
if (!options.ignoreExitCode && result.code !== 0) {
|
|
139
146
|
state.actions.debug(log.non_zero_exit(result));
|
package/src/core/git.ts
CHANGED
|
@@ -61,7 +61,7 @@ export async function get_diff(commit_list: CommitList) {
|
|
|
61
61
|
const first_commit = commit_list[0];
|
|
62
62
|
const last_commit = commit_list[commit_list.length - 1];
|
|
63
63
|
const sha_range = `${first_commit.sha}~1..${last_commit.sha}`;
|
|
64
|
-
const diff_result = await cli(`git --no-pager diff --color=never ${sha_range}
|
|
64
|
+
const diff_result = await cli(`git --no-pager diff --color=never ${sha_range}`, { quiet: true });
|
|
65
65
|
return diff_result.stdout;
|
|
66
66
|
}
|
|
67
67
|
|
package/src/core/github.tsx
CHANGED
|
@@ -40,7 +40,6 @@ export async function pr_list(): Promise<Array<PullRequest>> {
|
|
|
40
40
|
if (actions.isDebug()) {
|
|
41
41
|
actions.output(
|
|
42
42
|
<FormatText
|
|
43
|
-
wrapper={<Ink.Text dimColor />}
|
|
44
43
|
message="Github cache {count} open PRs from {repo_path} authored by {username}"
|
|
45
44
|
values={{
|
|
46
45
|
count: (
|
|
@@ -101,7 +100,8 @@ export async function pr_status(branch: string): Promise<null | PullRequest> {
|
|
|
101
100
|
);
|
|
102
101
|
}
|
|
103
102
|
|
|
104
|
-
const
|
|
103
|
+
const commmand = `pr view ${branch} --repo ${repo_path} ${JSON_FIELDS}`;
|
|
104
|
+
const pr = await gh_json<PullRequest>(commmand, { branch });
|
|
105
105
|
|
|
106
106
|
if (pr instanceof Error) {
|
|
107
107
|
return null;
|
|
@@ -241,48 +241,37 @@ export async function pr_draft(args: DraftPullRequestArgs) {
|
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
-
export async function pr_diff(
|
|
245
|
-
|
|
246
|
-
const
|
|
244
|
+
export async function pr_diff(branch: string) {
|
|
245
|
+
// https://cli.github.com/manual/gh_pr_diff
|
|
246
|
+
const result = await gh(`pr diff --color=never ${branch}`, { branch });
|
|
247
247
|
|
|
248
|
-
|
|
248
|
+
if (result instanceof Error) {
|
|
249
|
+
handle_error(result.message);
|
|
250
|
+
}
|
|
249
251
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
actions.debug(
|
|
253
|
-
cache_message({
|
|
254
|
-
hit: true,
|
|
255
|
-
message: "Github pr_diff cache",
|
|
256
|
-
extra: number,
|
|
257
|
-
}),
|
|
258
|
-
);
|
|
259
|
-
}
|
|
252
|
+
return result;
|
|
253
|
+
}
|
|
260
254
|
|
|
261
|
-
|
|
262
|
-
|
|
255
|
+
export async function pr_compare(branch: string) {
|
|
256
|
+
const state = Store.getState();
|
|
257
|
+
const master_branch = state.master_branch;
|
|
258
|
+
const repo_path = state.repo_path;
|
|
259
|
+
invariant(master_branch, "master_branch must exist");
|
|
260
|
+
invariant(repo_path, "repo_path must exist");
|
|
263
261
|
|
|
264
|
-
|
|
265
|
-
actions.debug(
|
|
266
|
-
cache_message({
|
|
267
|
-
hit: false,
|
|
268
|
-
message: "Github pr_diff cache",
|
|
269
|
-
extra: number,
|
|
270
|
-
}),
|
|
271
|
-
);
|
|
272
|
-
}
|
|
262
|
+
const master_branch_name = master_branch.replace(/^origin\//, "");
|
|
273
263
|
|
|
274
|
-
//
|
|
275
|
-
const
|
|
264
|
+
// gh api repos/openai/openai/compare/master...chrome/publish/vine-1211---4h2xmw0o3ndvnt
|
|
265
|
+
const result = await gh_json<BranchCompare>(
|
|
266
|
+
`api repos/${repo_path}/compare/${master_branch_name}...${branch}`,
|
|
267
|
+
{ branch },
|
|
268
|
+
);
|
|
276
269
|
|
|
277
|
-
if (
|
|
278
|
-
handle_error(
|
|
270
|
+
if (result instanceof Error) {
|
|
271
|
+
handle_error(result.message);
|
|
279
272
|
}
|
|
280
273
|
|
|
281
|
-
|
|
282
|
-
state.cache_pr_diff[number] = cli_result.output;
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
return cli_result.stdout;
|
|
274
|
+
return result;
|
|
286
275
|
}
|
|
287
276
|
|
|
288
277
|
// pull request JSON fields
|
|
@@ -290,29 +279,99 @@ export async function pr_diff(number: number) {
|
|
|
290
279
|
// prettier-ignore
|
|
291
280
|
const JSON_FIELDS = "--json id,number,state,baseRefName,headRefName,commits,title,body,url,isDraft";
|
|
292
281
|
|
|
282
|
+
type GhCmdOptions = {
|
|
283
|
+
branch?: string;
|
|
284
|
+
};
|
|
285
|
+
|
|
293
286
|
// consistent handle gh cli commands returning json
|
|
294
287
|
// redirect to tmp file to avoid scrollback overflow causing scrollback to be cleared
|
|
295
|
-
async function gh_json<T>(command: string): Promise<T | Error> {
|
|
288
|
+
async function gh_json<T>(command: string, gh_options?: GhCmdOptions): Promise<T | Error> {
|
|
289
|
+
const gh_result = await gh(command, gh_options);
|
|
290
|
+
|
|
291
|
+
if (gh_result instanceof Error) {
|
|
292
|
+
return gh_result;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
try {
|
|
296
|
+
const json = JSON.parse(gh_result);
|
|
297
|
+
return json as T;
|
|
298
|
+
} catch (error) {
|
|
299
|
+
return new Error(`gh_json JSON.parse: ${error}`);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// consistent handle gh cli commands
|
|
304
|
+
// redirect to tmp file to avoid scrollback overflow causing scrollback to be cleared
|
|
305
|
+
async function gh(command: string, gh_options?: GhCmdOptions): Promise<string | Error> {
|
|
306
|
+
const state = Store.getState();
|
|
307
|
+
const actions = state.actions;
|
|
308
|
+
|
|
309
|
+
if (gh_options?.branch) {
|
|
310
|
+
const branch = gh_options.branch;
|
|
311
|
+
|
|
312
|
+
type CacheEntryByHeadRefName = (typeof state.cache_gh_cli_by_branch)[string][string];
|
|
313
|
+
|
|
314
|
+
let cache: undefined | CacheEntryByHeadRefName = undefined;
|
|
315
|
+
|
|
316
|
+
if (branch) {
|
|
317
|
+
if (state.cache_gh_cli_by_branch[branch]) {
|
|
318
|
+
cache = state.cache_gh_cli_by_branch[branch][command];
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (cache) {
|
|
323
|
+
if (actions.isDebug()) {
|
|
324
|
+
actions.debug(
|
|
325
|
+
cache_message({
|
|
326
|
+
hit: true,
|
|
327
|
+
message: "gh cache",
|
|
328
|
+
extra: command,
|
|
329
|
+
}),
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return cache;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (actions.isDebug()) {
|
|
337
|
+
actions.debug(
|
|
338
|
+
cache_message({
|
|
339
|
+
hit: false,
|
|
340
|
+
message: "gh cache",
|
|
341
|
+
extra: command,
|
|
342
|
+
}),
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
296
347
|
// hash command for unique short string
|
|
297
348
|
let hash = crypto.createHash("md5").update(command).digest("hex");
|
|
298
|
-
let tmp_filename = safe_filename(`
|
|
299
|
-
const
|
|
349
|
+
let tmp_filename = safe_filename(`gh-${hash}`);
|
|
350
|
+
const tmp_filepath = path.join(await get_tmp_dir(), `${tmp_filename}`);
|
|
300
351
|
|
|
301
352
|
const options = { ignoreExitCode: true };
|
|
302
|
-
const cli_result = await cli(`gh ${command} > ${
|
|
353
|
+
const cli_result = await cli(`gh ${command} > ${tmp_filepath}`, options);
|
|
303
354
|
|
|
304
355
|
if (cli_result.code !== 0) {
|
|
305
356
|
return new Error(cli_result.output);
|
|
306
357
|
}
|
|
307
358
|
|
|
308
359
|
// read from file
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
360
|
+
let content = String(await fs.readFile(tmp_filepath));
|
|
361
|
+
content = content.trim();
|
|
362
|
+
|
|
363
|
+
if (gh_options?.branch) {
|
|
364
|
+
const branch = gh_options.branch;
|
|
365
|
+
|
|
366
|
+
actions.set((state) => {
|
|
367
|
+
if (!state.cache_gh_cli_by_branch[branch]) {
|
|
368
|
+
state.cache_gh_cli_by_branch[branch] = {};
|
|
369
|
+
}
|
|
370
|
+
state.cache_gh_cli_by_branch[branch][command] = content;
|
|
371
|
+
});
|
|
315
372
|
}
|
|
373
|
+
|
|
374
|
+
return content;
|
|
316
375
|
}
|
|
317
376
|
|
|
318
377
|
function handle_error(output: string): never {
|
|
@@ -408,6 +467,36 @@ export type PullRequest = {
|
|
|
408
467
|
isDraft: boolean;
|
|
409
468
|
};
|
|
410
469
|
|
|
470
|
+
type MergeBaseCommit = {
|
|
471
|
+
author: unknown;
|
|
472
|
+
comments_url: string;
|
|
473
|
+
commit: unknown;
|
|
474
|
+
committer: unknown;
|
|
475
|
+
html_url: string;
|
|
476
|
+
node_id: string;
|
|
477
|
+
parents: unknown;
|
|
478
|
+
sha: string;
|
|
479
|
+
url: string;
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
export type BranchCompare = {
|
|
483
|
+
ahead_by: number;
|
|
484
|
+
base_commit: unknown;
|
|
485
|
+
behind_by: number;
|
|
486
|
+
commits: unknown;
|
|
487
|
+
diff_url: string;
|
|
488
|
+
|
|
489
|
+
files: unknown;
|
|
490
|
+
html_url: string;
|
|
491
|
+
|
|
492
|
+
merge_base_commit: MergeBaseCommit;
|
|
493
|
+
patch_url: string;
|
|
494
|
+
permalink_url: string;
|
|
495
|
+
status: unknown;
|
|
496
|
+
total_commits: number;
|
|
497
|
+
url: string;
|
|
498
|
+
};
|
|
499
|
+
|
|
411
500
|
const RE = {
|
|
412
501
|
non_alphanumeric_dash: /[^a-zA-Z0-9_-]+/g,
|
|
413
502
|
};
|
package/src/index.tsx
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
|
|
7
7
|
import fs from "node:fs/promises";
|
|
8
|
-
import path from "node:path";
|
|
9
8
|
|
|
10
9
|
import * as Ink from "ink-cjs";
|
|
11
10
|
|
|
@@ -61,10 +60,6 @@ import { pretty_json } from "~/core/pretty_json";
|
|
|
61
60
|
|
|
62
61
|
actions.debug(pretty_json(argv as any));
|
|
63
62
|
|
|
64
|
-
const PATH = process.env["PATH"];
|
|
65
|
-
const PATH_LIST = pretty_json(PATH.split(path.delimiter));
|
|
66
|
-
actions.debug(`process.env.PATH ${PATH_LIST}`);
|
|
67
|
-
|
|
68
63
|
await ink.waitUntilExit();
|
|
69
64
|
|
|
70
65
|
function maybe_verbose_help() {
|
package/src/types/global.d.ts
CHANGED
package/src/app/LogTimestamp.tsx
DELETED