git-stack-cli 2.7.0 → 2.7.2
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 +326 -287
- package/package.json +1 -1
- package/scripts/bun-build.ts +2 -1
- package/scripts/core/get_local_iso.ts +20 -0
- package/src/app/AutoUpdate.tsx +203 -176
- package/src/app/SelectCommitRanges.tsx +14 -16
- package/src/commands/Rebase.tsx +4 -0
- package/src/core/CommitMetadata.ts +8 -60
- package/src/core/Metadata.test.ts +3 -0
- package/src/core/Metadata.ts +11 -1
- package/src/core/__snapshots__/git.test.ts.snap +95 -0
- package/src/core/get_timeout_fn.ts +11 -0
- package/src/core/git.test.ts +54 -0
- package/src/core/git.ts +55 -0
- package/src/core/github.tsx +6 -0
|
@@ -17,6 +17,7 @@ test("read handles bulleted lists", () => {
|
|
|
17
17
|
const metadata = Metadata.read(body);
|
|
18
18
|
|
|
19
19
|
expect(metadata).toEqual({
|
|
20
|
+
subject: "[feat] implement various features",
|
|
20
21
|
id: "DdKIFyufW",
|
|
21
22
|
title: "saved group title",
|
|
22
23
|
});
|
|
@@ -63,6 +64,7 @@ test("read handles slashes in branch name", () => {
|
|
|
63
64
|
const metadata = Metadata.read(body);
|
|
64
65
|
|
|
65
66
|
expect(metadata).toEqual({
|
|
67
|
+
subject: "[fix] slash in branch name",
|
|
66
68
|
id: "dev/noah/fix-slash-branch",
|
|
67
69
|
title: "fix slash branch",
|
|
68
70
|
});
|
|
@@ -109,6 +111,7 @@ test("read handles double quotes", () => {
|
|
|
109
111
|
const metadata = Metadata.read(body);
|
|
110
112
|
|
|
111
113
|
expect(metadata).toEqual({
|
|
114
|
+
subject: 'Revert "[abc / 123] subject (#1234)"',
|
|
112
115
|
id: "dev/noah/fix-slash-branch",
|
|
113
116
|
title: 'Revert \\"[abc / 123] subject (#1234)\\"',
|
|
114
117
|
});
|
package/src/core/Metadata.ts
CHANGED
|
@@ -6,6 +6,7 @@ type InputMetadataValues = {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
type OutputMetadataValues = {
|
|
9
|
+
subject: null | string;
|
|
9
10
|
id: null | string;
|
|
10
11
|
title: null | string;
|
|
11
12
|
};
|
|
@@ -28,7 +29,14 @@ export function write(message: string, values: InputMetadataValues) {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export function read(message: string): OutputMetadataValues {
|
|
31
|
-
const values: OutputMetadataValues = { id: null, title: null };
|
|
32
|
+
const values: OutputMetadataValues = { subject: null, id: null, title: null };
|
|
33
|
+
|
|
34
|
+
const match_subject = message.match(RE.subject_line);
|
|
35
|
+
|
|
36
|
+
if (match_subject?.groups) {
|
|
37
|
+
values.subject = match_subject.groups["subject"];
|
|
38
|
+
invariant(values.subject, "subject must exist");
|
|
39
|
+
}
|
|
32
40
|
|
|
33
41
|
const match_id = message.match(RE.stack_id);
|
|
34
42
|
|
|
@@ -69,6 +77,8 @@ const TEMPLATE = {
|
|
|
69
77
|
};
|
|
70
78
|
|
|
71
79
|
const RE = {
|
|
80
|
+
// https://regex101.com/r/pOrChS/1
|
|
81
|
+
subject_line: /^(?<subject>[^\n]*)/,
|
|
72
82
|
// https://regex101.com/r/wLmGVq/1
|
|
73
83
|
stack_id: new RegExp(`${TEMPLATE.stack_id("(?<id>[^\\s]+)")}`, "i"),
|
|
74
84
|
group_title: new RegExp(TEMPLATE.group_title("(?<title>[^\\n^\\r]+)"), "i"),
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// Bun Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`get_commits ABC..DEF:
|
|
4
|
+
[
|
|
5
|
+
{
|
|
6
|
+
"branch_id": null,
|
|
7
|
+
"full_message": "homebrew-git-stack 2.7.1",
|
|
8
|
+
"sha": "ba067f8ad641dda7e65e3c2acb2421c955843829",
|
|
9
|
+
"subject_line": "homebrew-git-stack 2.7.1",
|
|
10
|
+
"title": null,
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"branch_id": "noah/paint-test---4gwpqhd033n6y5",
|
|
14
|
+
"full_message":
|
|
15
|
+
"Rebase: debug logs
|
|
16
|
+
|
|
17
|
+
git-stack-id: noah/paint-test---4gwpqhd033n6y5
|
|
18
|
+
git-stack-title: Rebase: debug logs"
|
|
19
|
+
,
|
|
20
|
+
"sha": "7c8da9f5fe681fc7459a0e737241df631983cd3c",
|
|
21
|
+
"subject_line": "Rebase: debug logs",
|
|
22
|
+
"title": "Rebase: debug logs",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"branch_id": "noah/paint-test---4gwpqirewoudxa",
|
|
26
|
+
"full_message":
|
|
27
|
+
"CommitMetadata: track last group id
|
|
28
|
+
|
|
29
|
+
git-stack-id: noah/paint-test---4gwpqirewoudxa
|
|
30
|
+
git-stack-title: CommitMetadata: track last group id"
|
|
31
|
+
,
|
|
32
|
+
"sha": "47a69d37f8c5cc796884a91fa9e93fc1db5297dd",
|
|
33
|
+
"subject_line": "CommitMetadata: track last group id",
|
|
34
|
+
"title": "CommitMetadata: track last group id",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"branch_id": "noah/paint-test---4gwpqjcpu7-isv",
|
|
38
|
+
"full_message":
|
|
39
|
+
"Github: pr_list duration timer
|
|
40
|
+
|
|
41
|
+
git-stack-id: noah/paint-test---4gwpqjcpu7-isv
|
|
42
|
+
git-stack-title: Github: pr_list duration timer"
|
|
43
|
+
,
|
|
44
|
+
"sha": "8ccf42a7c72aa194fafc7c326f5874f5a0a009c6",
|
|
45
|
+
"subject_line": "Github: pr_list duration timer",
|
|
46
|
+
"title": "Github: pr_list duration timer",
|
|
47
|
+
},
|
|
48
|
+
]
|
|
49
|
+
1`] = `
|
|
50
|
+
[
|
|
51
|
+
{
|
|
52
|
+
"branch_id": null,
|
|
53
|
+
"full_message": "homebrew-git-stack 2.7.1",
|
|
54
|
+
"sha": "ba067f8ad641dda7e65e3c2acb2421c955843829",
|
|
55
|
+
"subject_line": "homebrew-git-stack 2.7.1",
|
|
56
|
+
"title": null,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"branch_id": "noah/paint-test---4gwpqhd033n6y5",
|
|
60
|
+
"full_message":
|
|
61
|
+
"Rebase: debug logs
|
|
62
|
+
|
|
63
|
+
git-stack-id: noah/paint-test---4gwpqhd033n6y5
|
|
64
|
+
git-stack-title: Rebase: debug logs"
|
|
65
|
+
,
|
|
66
|
+
"sha": "7c8da9f5fe681fc7459a0e737241df631983cd3c",
|
|
67
|
+
"subject_line": "Rebase: debug logs",
|
|
68
|
+
"title": "Rebase: debug logs",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"branch_id": "noah/paint-test---4gwpqirewoudxa",
|
|
72
|
+
"full_message":
|
|
73
|
+
"CommitMetadata: track last group id
|
|
74
|
+
|
|
75
|
+
git-stack-id: noah/paint-test---4gwpqirewoudxa
|
|
76
|
+
git-stack-title: CommitMetadata: track last group id"
|
|
77
|
+
,
|
|
78
|
+
"sha": "47a69d37f8c5cc796884a91fa9e93fc1db5297dd",
|
|
79
|
+
"subject_line": "CommitMetadata: track last group id",
|
|
80
|
+
"title": "CommitMetadata: track last group id",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"branch_id": "noah/paint-test---4gwpqjcpu7-isv",
|
|
84
|
+
"full_message":
|
|
85
|
+
"Github: pr_list duration timer
|
|
86
|
+
|
|
87
|
+
git-stack-id: noah/paint-test---4gwpqjcpu7-isv
|
|
88
|
+
git-stack-title: Github: pr_list duration timer"
|
|
89
|
+
,
|
|
90
|
+
"sha": "8ccf42a7c72aa194fafc7c326f5874f5a0a009c6",
|
|
91
|
+
"subject_line": "Github: pr_list duration timer",
|
|
92
|
+
"title": "Github: pr_list duration timer",
|
|
93
|
+
},
|
|
94
|
+
]
|
|
95
|
+
`;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function get_timeout_fn(ms: number, message: string) {
|
|
2
|
+
return function timeout<T>(promise: Promise<T>) {
|
|
3
|
+
let id: ReturnType<typeof setTimeout>;
|
|
4
|
+
|
|
5
|
+
const timeout = new Promise<never>((_resolve, reject) => {
|
|
6
|
+
id = setTimeout(() => reject(new Error(message)), ms);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
return Promise.race([promise, timeout]).finally(() => clearTimeout(id));
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { test, expect } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import * as git from "~/core/git";
|
|
4
|
+
|
|
5
|
+
test("get_commits ABC..DEF", async () => {
|
|
6
|
+
const commits = await git.get_commits("e781ede..8ccf42a");
|
|
7
|
+
expect(commits).toMatchSnapshot(`
|
|
8
|
+
[
|
|
9
|
+
{
|
|
10
|
+
"branch_id": null,
|
|
11
|
+
"full_message": "homebrew-git-stack 2.7.1",
|
|
12
|
+
"sha": "ba067f8ad641dda7e65e3c2acb2421c955843829",
|
|
13
|
+
"subject_line": "homebrew-git-stack 2.7.1",
|
|
14
|
+
"title": null,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"branch_id": "noah/paint-test---4gwpqhd033n6y5",
|
|
18
|
+
"full_message":
|
|
19
|
+
"Rebase: debug logs
|
|
20
|
+
|
|
21
|
+
git-stack-id: noah/paint-test---4gwpqhd033n6y5
|
|
22
|
+
git-stack-title: Rebase: debug logs"
|
|
23
|
+
,
|
|
24
|
+
"sha": "7c8da9f5fe681fc7459a0e737241df631983cd3c",
|
|
25
|
+
"subject_line": "Rebase: debug logs",
|
|
26
|
+
"title": "Rebase: debug logs",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"branch_id": "noah/paint-test---4gwpqirewoudxa",
|
|
30
|
+
"full_message":
|
|
31
|
+
"CommitMetadata: track last group id
|
|
32
|
+
|
|
33
|
+
git-stack-id: noah/paint-test---4gwpqirewoudxa
|
|
34
|
+
git-stack-title: CommitMetadata: track last group id"
|
|
35
|
+
,
|
|
36
|
+
"sha": "47a69d37f8c5cc796884a91fa9e93fc1db5297dd",
|
|
37
|
+
"subject_line": "CommitMetadata: track last group id",
|
|
38
|
+
"title": "CommitMetadata: track last group id",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"branch_id": "noah/paint-test---4gwpqjcpu7-isv",
|
|
42
|
+
"full_message":
|
|
43
|
+
"Github: pr_list duration timer
|
|
44
|
+
|
|
45
|
+
git-stack-id: noah/paint-test---4gwpqjcpu7-isv
|
|
46
|
+
git-stack-title: Github: pr_list duration timer"
|
|
47
|
+
,
|
|
48
|
+
"sha": "8ccf42a7c72aa194fafc7c326f5874f5a0a009c6",
|
|
49
|
+
"subject_line": "Github: pr_list duration timer",
|
|
50
|
+
"title": "Github: pr_list duration timer",
|
|
51
|
+
},
|
|
52
|
+
]
|
|
53
|
+
`);
|
|
54
|
+
});
|
package/src/core/git.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as Metadata from "~/core/Metadata";
|
|
2
|
+
import { cli } from "~/core/cli";
|
|
3
|
+
|
|
4
|
+
export type Commit = Awaited<ReturnType<typeof get_commits>>[0];
|
|
5
|
+
|
|
6
|
+
export async function get_commits(dot_range: string) {
|
|
7
|
+
const log_result = await cli(`git log ${dot_range} --format=${FORMAT} --color=never`);
|
|
8
|
+
|
|
9
|
+
if (!log_result.stdout) {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const commit_list = [];
|
|
14
|
+
|
|
15
|
+
for (let record of log_result.stdout.split(SEP.record)) {
|
|
16
|
+
record = record.replace(/^\n/, "");
|
|
17
|
+
record = record.replace(/\n$/, "");
|
|
18
|
+
|
|
19
|
+
if (!record) continue;
|
|
20
|
+
|
|
21
|
+
const [sha, full_message] = record.split(SEP.field);
|
|
22
|
+
|
|
23
|
+
const metadata = Metadata.read(full_message);
|
|
24
|
+
const branch_id = metadata.id;
|
|
25
|
+
const subject_line = metadata.subject || "";
|
|
26
|
+
const title = metadata.title;
|
|
27
|
+
|
|
28
|
+
const commit = {
|
|
29
|
+
sha,
|
|
30
|
+
full_message,
|
|
31
|
+
subject_line,
|
|
32
|
+
branch_id,
|
|
33
|
+
title,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
commit_list.push(commit);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
commit_list.reverse();
|
|
40
|
+
|
|
41
|
+
return commit_list;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Why these separators?
|
|
45
|
+
// - Rare in human written text
|
|
46
|
+
// - Supported in git %xNN to write bytes
|
|
47
|
+
// - Supported in javascript \xNN to write bytes
|
|
48
|
+
// - Used historically as separators in unicode
|
|
49
|
+
// https://en.wikipedia.org/wiki/C0_and_C1_control_codes#Field_separators
|
|
50
|
+
const SEP = {
|
|
51
|
+
record: "\x1e",
|
|
52
|
+
field: "\x1f",
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const FORMAT = `%H${SEP.field}%B${SEP.record}`;
|
package/src/core/github.tsx
CHANGED
|
@@ -8,6 +8,7 @@ import * as Ink from "ink-cjs";
|
|
|
8
8
|
|
|
9
9
|
import { Brackets } from "~/app/Brackets";
|
|
10
10
|
import { Store } from "~/app/Store";
|
|
11
|
+
import { Timer } from "~/core/Timer";
|
|
11
12
|
import { cli } from "~/core/cli";
|
|
12
13
|
import { colors } from "~/core/colors";
|
|
13
14
|
import { get_tmp_dir } from "~/core/get_tmp_dir";
|
|
@@ -19,6 +20,9 @@ export async function pr_list(): Promise<Array<PullRequest>> {
|
|
|
19
20
|
const state = Store.getState();
|
|
20
21
|
const actions = state.actions;
|
|
21
22
|
|
|
23
|
+
const timer = Timer();
|
|
24
|
+
actions.debug("start github.pr_list");
|
|
25
|
+
|
|
22
26
|
const username = state.username;
|
|
23
27
|
const repo_path = state.repo_path;
|
|
24
28
|
invariant(username, "username must exist");
|
|
@@ -53,6 +57,8 @@ export async function pr_list(): Promise<Array<PullRequest>> {
|
|
|
53
57
|
}
|
|
54
58
|
});
|
|
55
59
|
|
|
60
|
+
const duration = timer.duration();
|
|
61
|
+
actions.debug(`end github.pr_list (duration=${duration})`);
|
|
56
62
|
return result_pr_list;
|
|
57
63
|
}
|
|
58
64
|
|