git-stack-cli 1.3.0 → 1.3.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/cjs/index.cjs +48 -29
- package/package.json +1 -1
- package/scripts/release-npm.ts +1 -29
- package/src/app/LocalMergeRebase.tsx +2 -1
- package/src/app/ManualRebase.tsx +6 -1
- package/src/app/SelectCommitRanges.tsx +38 -17
- package/src/app/Status.tsx +0 -9
- package/src/core/CommitMetadata.ts +5 -2
- package/src/core/GitReviseTodo.test.ts +25 -0
- package/src/core/GitReviseTodo.ts +2 -1
- package/src/core/Metadata.test.ts +37 -2
- package/src/core/Metadata.ts +36 -9
package/dist/cjs/index.cjs
CHANGED
|
@@ -27128,29 +27128,37 @@ const RE$2 = {
|
|
|
27128
27128
|
all_double_quote: /"/g,
|
|
27129
27129
|
};
|
|
27130
27130
|
|
|
27131
|
-
function write$1(message,
|
|
27131
|
+
function write$1(message, values) {
|
|
27132
27132
|
let result = message;
|
|
27133
27133
|
// escape double-quote for cli
|
|
27134
27134
|
result = safe_quote(result);
|
|
27135
27135
|
// remove any previous metadata lines
|
|
27136
27136
|
result = remove(result);
|
|
27137
|
-
const line_list = [result, "", TEMPLATE$1.stack_id(
|
|
27137
|
+
const line_list = [result, "", TEMPLATE$1.stack_id(values.id)];
|
|
27138
|
+
if (values.title) {
|
|
27139
|
+
line_list.push(TEMPLATE$1.group_title(values.title));
|
|
27140
|
+
}
|
|
27138
27141
|
const new_message = line_list.join("\n");
|
|
27139
27142
|
return new_message;
|
|
27140
27143
|
}
|
|
27141
27144
|
function read(message) {
|
|
27142
|
-
const
|
|
27143
|
-
|
|
27144
|
-
|
|
27145
|
+
const values = { id: null, title: null };
|
|
27146
|
+
const match_id = message.match(RE$1.stack_id);
|
|
27147
|
+
if (match_id?.groups) {
|
|
27148
|
+
values.id = match_id.groups["id"];
|
|
27149
|
+
invariant(values.id, "id must exist");
|
|
27145
27150
|
}
|
|
27146
|
-
const
|
|
27147
|
-
|
|
27148
|
-
|
|
27151
|
+
const match_title = message.match(RE$1.group_title);
|
|
27152
|
+
if (match_title?.groups) {
|
|
27153
|
+
values.title = match_title.groups["title"];
|
|
27154
|
+
}
|
|
27155
|
+
return values;
|
|
27149
27156
|
}
|
|
27150
27157
|
function remove(message) {
|
|
27151
27158
|
let result = message;
|
|
27152
27159
|
// remove metadata
|
|
27153
27160
|
result = result.replace(new RegExp(RE$1.stack_id, "gmi"), "");
|
|
27161
|
+
result = result.replace(new RegExp(RE$1.group_title, "gmi"), "");
|
|
27154
27162
|
result = result.trimEnd();
|
|
27155
27163
|
return result;
|
|
27156
27164
|
}
|
|
@@ -27158,9 +27166,13 @@ const TEMPLATE$1 = {
|
|
|
27158
27166
|
stack_id(id) {
|
|
27159
27167
|
return `git-stack-id: ${id}`;
|
|
27160
27168
|
},
|
|
27169
|
+
group_title(title) {
|
|
27170
|
+
return `git-stack-title: ${title}`;
|
|
27171
|
+
},
|
|
27161
27172
|
};
|
|
27162
27173
|
const RE$1 = {
|
|
27163
27174
|
stack_id: new RegExp(TEMPLATE$1.stack_id("(?<id>[a-z0-9-+=]+)"), "i"),
|
|
27175
|
+
group_title: new RegExp(TEMPLATE$1.group_title("(?<title>[^\\n^\\r]+)"), "i"),
|
|
27164
27176
|
};
|
|
27165
27177
|
|
|
27166
27178
|
// prettier-ignore
|
|
@@ -27282,7 +27294,7 @@ async function range(commit_group_map) {
|
|
|
27282
27294
|
const group_map = new Map();
|
|
27283
27295
|
for (const commit of commit_list) {
|
|
27284
27296
|
let id = commit.branch_id;
|
|
27285
|
-
let title = id;
|
|
27297
|
+
let title = commit.title || id;
|
|
27286
27298
|
// use commit map if provided (via select commit ranges)
|
|
27287
27299
|
if (commit_group_map) {
|
|
27288
27300
|
const group = commit_group_map[commit.sha];
|
|
@@ -27409,13 +27421,16 @@ async function get_commit_list() {
|
|
|
27409
27421
|
}
|
|
27410
27422
|
async function commit(sha) {
|
|
27411
27423
|
const full_message = (await cli(`git show -s --format=%B ${sha}`)).stdout;
|
|
27412
|
-
const
|
|
27424
|
+
const metadata = await read(full_message);
|
|
27425
|
+
const branch_id = metadata?.id;
|
|
27413
27426
|
const subject_line = get_subject_line(full_message);
|
|
27427
|
+
const title = metadata?.title;
|
|
27414
27428
|
return {
|
|
27415
27429
|
sha,
|
|
27416
27430
|
full_message,
|
|
27417
27431
|
subject_line,
|
|
27418
27432
|
branch_id,
|
|
27433
|
+
title,
|
|
27419
27434
|
};
|
|
27420
27435
|
}
|
|
27421
27436
|
function get_subject_line(message) {
|
|
@@ -27582,7 +27597,8 @@ async function run$3() {
|
|
|
27582
27597
|
await cli(`git add --all`);
|
|
27583
27598
|
let new_message;
|
|
27584
27599
|
if (commit.branch_id) {
|
|
27585
|
-
|
|
27600
|
+
const metadata = { id: commit.branch_id };
|
|
27601
|
+
new_message = write$1(commit.full_message, metadata);
|
|
27586
27602
|
}
|
|
27587
27603
|
else {
|
|
27588
27604
|
new_message = commit.full_message;
|
|
@@ -27716,7 +27732,8 @@ function GitReviseTodo(args) {
|
|
|
27716
27732
|
const group = group_list[i];
|
|
27717
27733
|
for (const commit of group.commits) {
|
|
27718
27734
|
// update git commit message with stack id
|
|
27719
|
-
const
|
|
27735
|
+
const metadata = { id: group.id, title: group.title };
|
|
27736
|
+
const message_with_id = write$1(commit.full_message, metadata);
|
|
27720
27737
|
// get first 12 characters of commit sha
|
|
27721
27738
|
const sha = commit.sha.slice(0, 12);
|
|
27722
27739
|
// generate git revise entry
|
|
@@ -27999,7 +28016,8 @@ echo "$GIT_REVISE_TODO" > "$git_revise_todo_path"
|
|
|
27999
28016
|
await cli(`rm ${PATCH_FILE}`);
|
|
28000
28017
|
// add all changes to stage
|
|
28001
28018
|
await cli(`git add --all`);
|
|
28002
|
-
const
|
|
28019
|
+
const metadata = { id: group.id, title: group.title };
|
|
28020
|
+
const new_message = write$1(commit.full_message, metadata);
|
|
28003
28021
|
const git_commit_comand = [`git commit -m "${new_message}"`];
|
|
28004
28022
|
if (argv.verify === false) {
|
|
28005
28023
|
git_commit_comand.push("--no-verify");
|
|
@@ -28070,6 +28088,9 @@ echo "$GIT_REVISE_TODO" > "$git_revise_todo_path"
|
|
|
28070
28088
|
}
|
|
28071
28089
|
}
|
|
28072
28090
|
async function update_pr_tables(pr_url_list) {
|
|
28091
|
+
if (!argv.sync) {
|
|
28092
|
+
return;
|
|
28093
|
+
}
|
|
28073
28094
|
for (let i = 0; i < commit_range.group_list.length; i++) {
|
|
28074
28095
|
const group = commit_range.group_list[i];
|
|
28075
28096
|
// use the updated pr_url_list to get the actual selected_url
|
|
@@ -28575,6 +28596,7 @@ function SelectCommitRanges() {
|
|
|
28575
28596
|
}
|
|
28576
28597
|
function SelectCommitRangesInternal(props) {
|
|
28577
28598
|
const actions = Store.useActions();
|
|
28599
|
+
const argv = Store.useState((state) => state.argv);
|
|
28578
28600
|
const [selected_group_id, set_selected_group_id] = reactExports.useState(props.commit_range.UNASSIGNED);
|
|
28579
28601
|
const [group_input, set_group_input] = reactExports.useState(false);
|
|
28580
28602
|
const [new_group_list, create_group] = reactExports.useReducer((group_list, group) => {
|
|
@@ -28616,7 +28638,7 @@ function SelectCommitRangesInternal(props) {
|
|
|
28616
28638
|
}
|
|
28617
28639
|
group_list.push({
|
|
28618
28640
|
id: group.id,
|
|
28619
|
-
title: group.pr?.title || group.id,
|
|
28641
|
+
title: group.pr?.title || group.title || group.id,
|
|
28620
28642
|
});
|
|
28621
28643
|
}
|
|
28622
28644
|
let current_index = group_list.findIndex((g) => g.id === selected_group_id);
|
|
@@ -28720,13 +28742,17 @@ function SelectCommitRangesInternal(props) {
|
|
|
28720
28742
|
create: (reactExports.createElement(Text, { bold: true, color: colors.green },
|
|
28721
28743
|
reactExports.createElement(Parens, null, "c"),
|
|
28722
28744
|
"reate")),
|
|
28723
|
-
} })) : (reactExports.createElement(reactExports.Fragment, null,
|
|
28724
|
-
|
|
28725
|
-
|
|
28726
|
-
|
|
28727
|
-
|
|
28728
|
-
|
|
28729
|
-
}
|
|
28745
|
+
} })) : (reactExports.createElement(reactExports.Fragment, null, argv.sync ? (reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, null), message: "\uD83C\uDF89 Done! Press {s} to {sync} the commits to Github", values: {
|
|
28746
|
+
s: (reactExports.createElement(Text, { bold: true, color: colors.green }, "s")),
|
|
28747
|
+
sync: (reactExports.createElement(Text, { bold: true, color: colors.green },
|
|
28748
|
+
reactExports.createElement(Parens, null, "s"),
|
|
28749
|
+
"ync")),
|
|
28750
|
+
} })) : (reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, null), message: "\uD83C\uDF89 Done! Press {s} to {save} the commits locally", values: {
|
|
28751
|
+
s: (reactExports.createElement(Text, { bold: true, color: colors.green }, "s")),
|
|
28752
|
+
save: (reactExports.createElement(Text, { bold: true, color: colors.green },
|
|
28753
|
+
reactExports.createElement(Parens, null, "s"),
|
|
28754
|
+
"save")),
|
|
28755
|
+
} })))),
|
|
28730
28756
|
!group_input ? null : (reactExports.createElement(reactExports.Fragment, null,
|
|
28731
28757
|
reactExports.createElement(Box, { height: 1 }),
|
|
28732
28758
|
reactExports.createElement(FormatText, { wrapper: reactExports.createElement(Text, { color: colors.gray }), message: "Enter a title for the PR {note}", values: {
|
|
@@ -28784,13 +28810,6 @@ async function run() {
|
|
|
28784
28810
|
needs_rebase = true;
|
|
28785
28811
|
}
|
|
28786
28812
|
}
|
|
28787
|
-
for (let i = 0; i < commit_range.commit_list.length; i++) {
|
|
28788
|
-
const commit = commit_range.commit_list[i];
|
|
28789
|
-
const commit_pr = commit_range.pr_lookup[commit.branch_id || ""];
|
|
28790
|
-
if (commit.branch_id && !commit_pr) {
|
|
28791
|
-
needs_rebase = true;
|
|
28792
|
-
}
|
|
28793
|
-
}
|
|
28794
28813
|
if (argv.check) {
|
|
28795
28814
|
actions.exit(0);
|
|
28796
28815
|
}
|
|
@@ -34316,7 +34335,7 @@ async function command() {
|
|
|
34316
34335
|
.wrap(123)
|
|
34317
34336
|
// disallow unknown options
|
|
34318
34337
|
.strict()
|
|
34319
|
-
.version("1.3.
|
|
34338
|
+
.version("1.3.2" )
|
|
34320
34339
|
.showHidden("show-hidden", "Show hidden options via `git stack help --show-hidden`")
|
|
34321
34340
|
.help("help", "Show usage via `git stack help`").argv);
|
|
34322
34341
|
}
|
package/package.json
CHANGED
package/scripts/release-npm.ts
CHANGED
|
@@ -52,7 +52,7 @@ for (const filepath of package_json.files) {
|
|
|
52
52
|
process.env.GS_RELEASE_NPM = "true";
|
|
53
53
|
console.info("Publishing to NPM requires a one-time password");
|
|
54
54
|
const otp = await input("Enter OTP: ");
|
|
55
|
-
await spawn(
|
|
55
|
+
await spawn(["npm", "publish", `--otp=${otp}`]);
|
|
56
56
|
|
|
57
57
|
process.chdir(PROJECT_DIR);
|
|
58
58
|
|
|
@@ -70,34 +70,6 @@ console.debug();
|
|
|
70
70
|
console.debug("https://www.npmjs.com/package/git-stack-cli");
|
|
71
71
|
console.debug();
|
|
72
72
|
|
|
73
|
-
// // https://github.com/magus/git-stack-cli/releases/download/0.8.9/git-stack-cli-linux
|
|
74
|
-
// async function create_asset(name: string) {
|
|
75
|
-
// const sha256_cmd = await spawn.sync(`shasum -a 256 ${name}`);
|
|
76
|
-
// const match = sha256_cmd.stdout.match(/(?<sha256>[^\s]+)/i);
|
|
77
|
-
|
|
78
|
-
// if (!match?.groups) {
|
|
79
|
-
// throw new Error(`unable to get sha256 for ${name}`);
|
|
80
|
-
// }
|
|
81
|
-
|
|
82
|
-
// const sha256 = match.groups.sha256;
|
|
83
|
-
|
|
84
|
-
// const url = `https://github.com/magus/git-stack-cli/releases/download/${version}/${name}`;
|
|
85
|
-
|
|
86
|
-
// return { name, sha256, url };
|
|
87
|
-
// }
|
|
88
|
-
|
|
89
|
-
// function reFind(list: Array<string>, re: RegExp) {
|
|
90
|
-
// for (const str of list) {
|
|
91
|
-
// const match = str.match(re);
|
|
92
|
-
|
|
93
|
-
// if (match?.groups) {
|
|
94
|
-
// return match.groups.value;
|
|
95
|
-
// }
|
|
96
|
-
// }
|
|
97
|
-
|
|
98
|
-
// return null;
|
|
99
|
-
// }
|
|
100
|
-
|
|
101
73
|
async function input(prompt: string) {
|
|
102
74
|
process.stdout.write(prompt);
|
|
103
75
|
for await (const value of console) {
|
|
@@ -112,7 +112,8 @@ async function run() {
|
|
|
112
112
|
|
|
113
113
|
let new_message;
|
|
114
114
|
if (commit.branch_id) {
|
|
115
|
-
|
|
115
|
+
const metadata = { id: commit.branch_id };
|
|
116
|
+
new_message = Metadata.write(commit.full_message, metadata);
|
|
116
117
|
} else {
|
|
117
118
|
new_message = commit.full_message;
|
|
118
119
|
}
|
package/src/app/ManualRebase.tsx
CHANGED
|
@@ -241,7 +241,8 @@ async function run() {
|
|
|
241
241
|
// add all changes to stage
|
|
242
242
|
await cli(`git add --all`);
|
|
243
243
|
|
|
244
|
-
const
|
|
244
|
+
const metadata = { id: group.id, title: group.title };
|
|
245
|
+
const new_message = Metadata.write(commit.full_message, metadata);
|
|
245
246
|
const git_commit_comand = [`git commit -m "${new_message}"`];
|
|
246
247
|
|
|
247
248
|
if (argv.verify === false) {
|
|
@@ -342,6 +343,10 @@ async function run() {
|
|
|
342
343
|
}
|
|
343
344
|
|
|
344
345
|
async function update_pr_tables(pr_url_list: Array<string>) {
|
|
346
|
+
if (!argv.sync) {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
345
350
|
for (let i = 0; i < commit_range.group_list.length; i++) {
|
|
346
351
|
const group = commit_range.group_list[i];
|
|
347
352
|
|
|
@@ -33,6 +33,8 @@ type SimpleGroup = { id: string; title: string };
|
|
|
33
33
|
function SelectCommitRangesInternal(props: Props) {
|
|
34
34
|
const actions = Store.useActions();
|
|
35
35
|
|
|
36
|
+
const argv = Store.useState((state) => state.argv);
|
|
37
|
+
|
|
36
38
|
const [selected_group_id, set_selected_group_id] = React.useState(
|
|
37
39
|
props.commit_range.UNASSIGNED
|
|
38
40
|
);
|
|
@@ -99,7 +101,7 @@ function SelectCommitRangesInternal(props: Props) {
|
|
|
99
101
|
|
|
100
102
|
group_list.push({
|
|
101
103
|
id: group.id,
|
|
102
|
-
title: group.pr?.title || group.id,
|
|
104
|
+
title: group.pr?.title || group.title || group.id,
|
|
103
105
|
});
|
|
104
106
|
}
|
|
105
107
|
|
|
@@ -259,22 +261,41 @@ function SelectCommitRangesInternal(props: Props) {
|
|
|
259
261
|
/>
|
|
260
262
|
) : (
|
|
261
263
|
<React.Fragment>
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
<
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
264
|
+
{argv.sync ? (
|
|
265
|
+
<FormatText
|
|
266
|
+
wrapper={<Ink.Text />}
|
|
267
|
+
message="🎉 Done! Press {s} to {sync} the commits to Github"
|
|
268
|
+
values={{
|
|
269
|
+
s: (
|
|
270
|
+
<Ink.Text bold color={colors.green}>
|
|
271
|
+
s
|
|
272
|
+
</Ink.Text>
|
|
273
|
+
),
|
|
274
|
+
sync: (
|
|
275
|
+
<Ink.Text bold color={colors.green}>
|
|
276
|
+
<Parens>s</Parens>ync
|
|
277
|
+
</Ink.Text>
|
|
278
|
+
),
|
|
279
|
+
}}
|
|
280
|
+
/>
|
|
281
|
+
) : (
|
|
282
|
+
<FormatText
|
|
283
|
+
wrapper={<Ink.Text />}
|
|
284
|
+
message="🎉 Done! Press {s} to {save} the commits locally"
|
|
285
|
+
values={{
|
|
286
|
+
s: (
|
|
287
|
+
<Ink.Text bold color={colors.green}>
|
|
288
|
+
s
|
|
289
|
+
</Ink.Text>
|
|
290
|
+
),
|
|
291
|
+
save: (
|
|
292
|
+
<Ink.Text bold color={colors.green}>
|
|
293
|
+
<Parens>s</Parens>save
|
|
294
|
+
</Ink.Text>
|
|
295
|
+
),
|
|
296
|
+
}}
|
|
297
|
+
/>
|
|
298
|
+
)}
|
|
278
299
|
</React.Fragment>
|
|
279
300
|
)}
|
|
280
301
|
|
package/src/app/Status.tsx
CHANGED
|
@@ -36,15 +36,6 @@ async function run() {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
for (let i = 0; i < commit_range.commit_list.length; i++) {
|
|
40
|
-
const commit = commit_range.commit_list[i];
|
|
41
|
-
const commit_pr = commit_range.pr_lookup[commit.branch_id || ""];
|
|
42
|
-
|
|
43
|
-
if (commit.branch_id && !commit_pr) {
|
|
44
|
-
needs_rebase = true;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
39
|
if (argv.check) {
|
|
49
40
|
actions.exit(0);
|
|
50
41
|
} else if (needs_rebase) {
|
|
@@ -36,7 +36,7 @@ export async function range(commit_group_map?: CommitGroupMap) {
|
|
|
36
36
|
|
|
37
37
|
for (const commit of commit_list) {
|
|
38
38
|
let id = commit.branch_id;
|
|
39
|
-
let title = id;
|
|
39
|
+
let title = commit.title || id;
|
|
40
40
|
|
|
41
41
|
// use commit map if provided (via select commit ranges)
|
|
42
42
|
if (commit_group_map) {
|
|
@@ -189,14 +189,17 @@ async function get_commit_list() {
|
|
|
189
189
|
|
|
190
190
|
export async function commit(sha: string) {
|
|
191
191
|
const full_message = (await cli(`git show -s --format=%B ${sha}`)).stdout;
|
|
192
|
-
const
|
|
192
|
+
const metadata = await Metadata.read(full_message);
|
|
193
|
+
const branch_id = metadata?.id;
|
|
193
194
|
const subject_line = get_subject_line(full_message);
|
|
195
|
+
const title = metadata?.title;
|
|
194
196
|
|
|
195
197
|
return {
|
|
196
198
|
sha,
|
|
197
199
|
full_message,
|
|
198
200
|
subject_line,
|
|
199
201
|
branch_id,
|
|
202
|
+
title,
|
|
200
203
|
};
|
|
201
204
|
}
|
|
202
205
|
|
|
@@ -16,21 +16,25 @@ test("git-revise-todo from commit range with single new commit", () => {
|
|
|
16
16
|
"lemon color",
|
|
17
17
|
"",
|
|
18
18
|
"git-stack-id: E63ytp5dj",
|
|
19
|
+
"git-stack-title: lemon color",
|
|
19
20
|
"",
|
|
20
21
|
"++ pick d36d63499425",
|
|
21
22
|
"cantaloupe color",
|
|
22
23
|
"",
|
|
23
24
|
"git-stack-id: E63ytp5dj",
|
|
25
|
+
"git-stack-title: lemon color",
|
|
24
26
|
"",
|
|
25
27
|
"++ pick 4f98dd3e67d0",
|
|
26
28
|
"banana sweet",
|
|
27
29
|
"",
|
|
28
30
|
"git-stack-id: E63ytp5dj",
|
|
31
|
+
"git-stack-title: lemon color",
|
|
29
32
|
"",
|
|
30
33
|
"++ pick f143d03c723c",
|
|
31
34
|
"apple sweet",
|
|
32
35
|
"",
|
|
33
36
|
"git-stack-id: E63ytp5dj",
|
|
37
|
+
"git-stack-title: lemon color",
|
|
34
38
|
].join("\n")
|
|
35
39
|
);
|
|
36
40
|
});
|
|
@@ -48,6 +52,7 @@ test("git-revise-todo from commit range with single new commit in new group", ()
|
|
|
48
52
|
"apple sweet",
|
|
49
53
|
"",
|
|
50
54
|
"git-stack-id: 6Ak-qn+5Z",
|
|
55
|
+
"git-stack-title: new group",
|
|
51
56
|
].join("\n")
|
|
52
57
|
);
|
|
53
58
|
});
|
|
@@ -93,6 +98,7 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
93
98
|
"full_message": "banana color\n\ngit-stack-id: AAWsYx1UU",
|
|
94
99
|
"subject_line": "banana color",
|
|
95
100
|
"branch_id": "AAWsYx1UU",
|
|
101
|
+
"title": null,
|
|
96
102
|
},
|
|
97
103
|
],
|
|
98
104
|
},
|
|
@@ -164,24 +170,28 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
164
170
|
"full_message": "lemon color\n\ngit-stack-id: E63ytp5dj",
|
|
165
171
|
"subject_line": "lemon color",
|
|
166
172
|
"branch_id": "E63ytp5dj",
|
|
173
|
+
"title": null,
|
|
167
174
|
},
|
|
168
175
|
{
|
|
169
176
|
"sha": "d36d63499425bb46a1e62c2c9df1a4332b13004f",
|
|
170
177
|
"full_message": "cantaloupe color\n\ngit-stack-id: E63ytp5dj",
|
|
171
178
|
"subject_line": "cantaloupe color",
|
|
172
179
|
"branch_id": "E63ytp5dj",
|
|
180
|
+
"title": null,
|
|
173
181
|
},
|
|
174
182
|
{
|
|
175
183
|
"sha": "4f98dd3e67d03b79d7a12480c7d1c2fcbd186ac5",
|
|
176
184
|
"full_message": "banana sweet\n\ngit-stack-id: E63ytp5dj",
|
|
177
185
|
"subject_line": "banana sweet",
|
|
178
186
|
"branch_id": "E63ytp5dj",
|
|
187
|
+
"title": null,
|
|
179
188
|
},
|
|
180
189
|
{
|
|
181
190
|
"sha": "f143d03c723c9f5231a81c1e12098511611898cb",
|
|
182
191
|
"full_message": "apple sweet",
|
|
183
192
|
"subject_line": "apple sweet",
|
|
184
193
|
"branch_id": null,
|
|
194
|
+
"title": null,
|
|
185
195
|
},
|
|
186
196
|
],
|
|
187
197
|
},
|
|
@@ -192,30 +202,35 @@ const SINGLE_COMMIT_EXISTING_GROUP: CommitMetadata.CommitRange = {
|
|
|
192
202
|
"full_message": "banana color\n\ngit-stack-id: AAWsYx1UU",
|
|
193
203
|
"subject_line": "banana color",
|
|
194
204
|
"branch_id": "AAWsYx1UU",
|
|
205
|
+
"title": null,
|
|
195
206
|
},
|
|
196
207
|
{
|
|
197
208
|
"sha": "3cb22661ecff6c872e96ce9c40b31c824938cab7",
|
|
198
209
|
"full_message": "lemon color\n\ngit-stack-id: E63ytp5dj",
|
|
199
210
|
"subject_line": "lemon color",
|
|
200
211
|
"branch_id": "E63ytp5dj",
|
|
212
|
+
"title": null,
|
|
201
213
|
},
|
|
202
214
|
{
|
|
203
215
|
"sha": "d36d63499425bb46a1e62c2c9df1a4332b13004f",
|
|
204
216
|
"full_message": "cantaloupe color\n\ngit-stack-id: E63ytp5dj",
|
|
205
217
|
"subject_line": "cantaloupe color",
|
|
206
218
|
"branch_id": "E63ytp5dj",
|
|
219
|
+
"title": null,
|
|
207
220
|
},
|
|
208
221
|
{
|
|
209
222
|
"sha": "4f98dd3e67d03b79d7a12480c7d1c2fcbd186ac5",
|
|
210
223
|
"full_message": "banana sweet\n\ngit-stack-id: E63ytp5dj",
|
|
211
224
|
"subject_line": "banana sweet",
|
|
212
225
|
"branch_id": "E63ytp5dj",
|
|
226
|
+
"title": null,
|
|
213
227
|
},
|
|
214
228
|
{
|
|
215
229
|
"sha": "f143d03c723c9f5231a81c1e12098511611898cb",
|
|
216
230
|
"full_message": "apple sweet",
|
|
217
231
|
"subject_line": "apple sweet",
|
|
218
232
|
"branch_id": null,
|
|
233
|
+
"title": null,
|
|
219
234
|
},
|
|
220
235
|
],
|
|
221
236
|
"pr_lookup": {
|
|
@@ -348,6 +363,7 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
348
363
|
"full_message": "banana color\n\ngit-stack-id: AAWsYx1UU",
|
|
349
364
|
"subject_line": "banana color",
|
|
350
365
|
"branch_id": "AAWsYx1UU",
|
|
366
|
+
"title": null,
|
|
351
367
|
},
|
|
352
368
|
],
|
|
353
369
|
},
|
|
@@ -419,18 +435,21 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
419
435
|
"full_message": "lemon color\n\ngit-stack-id: E63ytp5dj",
|
|
420
436
|
"subject_line": "lemon color",
|
|
421
437
|
"branch_id": "E63ytp5dj",
|
|
438
|
+
"title": null,
|
|
422
439
|
},
|
|
423
440
|
{
|
|
424
441
|
"sha": "d36d63499425bb46a1e62c2c9df1a4332b13004f",
|
|
425
442
|
"full_message": "cantaloupe color\n\ngit-stack-id: E63ytp5dj",
|
|
426
443
|
"subject_line": "cantaloupe color",
|
|
427
444
|
"branch_id": "E63ytp5dj",
|
|
445
|
+
"title": null,
|
|
428
446
|
},
|
|
429
447
|
{
|
|
430
448
|
"sha": "4f98dd3e67d03b79d7a12480c7d1c2fcbd186ac5",
|
|
431
449
|
"full_message": "banana sweet\n\ngit-stack-id: E63ytp5dj",
|
|
432
450
|
"subject_line": "banana sweet",
|
|
433
451
|
"branch_id": "E63ytp5dj",
|
|
452
|
+
"title": null,
|
|
434
453
|
},
|
|
435
454
|
],
|
|
436
455
|
},
|
|
@@ -446,6 +465,7 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
446
465
|
"full_message": "apple sweet",
|
|
447
466
|
"subject_line": "apple sweet",
|
|
448
467
|
"branch_id": null,
|
|
468
|
+
"title": null,
|
|
449
469
|
},
|
|
450
470
|
],
|
|
451
471
|
},
|
|
@@ -456,30 +476,35 @@ const SINGLE_COMMIT_NEW_GROUP: CommitMetadata.CommitRange = {
|
|
|
456
476
|
"full_message": "banana color\n\ngit-stack-id: AAWsYx1UU",
|
|
457
477
|
"subject_line": "banana color",
|
|
458
478
|
"branch_id": "AAWsYx1UU",
|
|
479
|
+
"title": null,
|
|
459
480
|
},
|
|
460
481
|
{
|
|
461
482
|
"sha": "3cb22661ecff6c872e96ce9c40b31c824938cab7",
|
|
462
483
|
"full_message": "lemon color\n\ngit-stack-id: E63ytp5dj",
|
|
463
484
|
"subject_line": "lemon color",
|
|
464
485
|
"branch_id": "E63ytp5dj",
|
|
486
|
+
"title": null,
|
|
465
487
|
},
|
|
466
488
|
{
|
|
467
489
|
"sha": "d36d63499425bb46a1e62c2c9df1a4332b13004f",
|
|
468
490
|
"full_message": "cantaloupe color\n\ngit-stack-id: E63ytp5dj",
|
|
469
491
|
"subject_line": "cantaloupe color",
|
|
470
492
|
"branch_id": "E63ytp5dj",
|
|
493
|
+
"title": null,
|
|
471
494
|
},
|
|
472
495
|
{
|
|
473
496
|
"sha": "4f98dd3e67d03b79d7a12480c7d1c2fcbd186ac5",
|
|
474
497
|
"full_message": "banana sweet\n\ngit-stack-id: E63ytp5dj",
|
|
475
498
|
"subject_line": "banana sweet",
|
|
476
499
|
"branch_id": "E63ytp5dj",
|
|
500
|
+
"title": null,
|
|
477
501
|
},
|
|
478
502
|
{
|
|
479
503
|
"sha": "f143d03c723c9f5231a81c1e12098511611898cb",
|
|
480
504
|
"full_message": "apple sweet",
|
|
481
505
|
"subject_line": "apple sweet",
|
|
482
506
|
"branch_id": null,
|
|
507
|
+
"title": null,
|
|
483
508
|
},
|
|
484
509
|
],
|
|
485
510
|
"pr_lookup": {
|
|
@@ -56,7 +56,8 @@ export function GitReviseTodo(args: Args): string {
|
|
|
56
56
|
|
|
57
57
|
for (const commit of group.commits) {
|
|
58
58
|
// update git commit message with stack id
|
|
59
|
-
const
|
|
59
|
+
const metadata = { id: group.id, title: group.title };
|
|
60
|
+
const message_with_id = Metadata.write(commit.full_message, metadata);
|
|
60
61
|
|
|
61
62
|
// get first 12 characters of commit sha
|
|
62
63
|
const sha = commit.sha.slice(0, 12);
|
|
@@ -11,9 +11,15 @@ test("read handles bulleted lists", () => {
|
|
|
11
11
|
"- move logic inside if branch",
|
|
12
12
|
"",
|
|
13
13
|
"git-stack-id: DdKIFyufW",
|
|
14
|
+
"git-stack-title: saved group title",
|
|
14
15
|
].join("\n");
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
const metadata = Metadata.read(body);
|
|
18
|
+
|
|
19
|
+
expect(metadata).toEqual({
|
|
20
|
+
id: "DdKIFyufW",
|
|
21
|
+
title: "saved group title",
|
|
22
|
+
});
|
|
17
23
|
});
|
|
18
24
|
|
|
19
25
|
test("write handles bulleted lists", () => {
|
|
@@ -27,7 +33,12 @@ test("write handles bulleted lists", () => {
|
|
|
27
33
|
"git-stack-id: DdKIFyufW",
|
|
28
34
|
].join("\n");
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
const metadata = {
|
|
37
|
+
id: "abcd1234",
|
|
38
|
+
title: "banana",
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
expect(Metadata.write(body, metadata)).toEqual(
|
|
31
42
|
[
|
|
32
43
|
"[feat] implement various features",
|
|
33
44
|
"",
|
|
@@ -36,6 +47,30 @@ test("write handles bulleted lists", () => {
|
|
|
36
47
|
"- move logic inside if branch",
|
|
37
48
|
"",
|
|
38
49
|
"git-stack-id: abcd1234",
|
|
50
|
+
"git-stack-title: banana",
|
|
51
|
+
].join("\n")
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("removes metadata", () => {
|
|
56
|
+
const body = [
|
|
57
|
+
"[feat] implement various features",
|
|
58
|
+
"",
|
|
59
|
+
"- keyboard modality escape key",
|
|
60
|
+
"- centralize settings",
|
|
61
|
+
"- move logic inside if branch",
|
|
62
|
+
"",
|
|
63
|
+
"git-stack-id: DdKIFyufW",
|
|
64
|
+
"git-stack-title: this is a PR title",
|
|
65
|
+
].join("\n");
|
|
66
|
+
|
|
67
|
+
expect(Metadata.remove(body)).toEqual(
|
|
68
|
+
[
|
|
69
|
+
"[feat] implement various features",
|
|
70
|
+
"",
|
|
71
|
+
"- keyboard modality escape key",
|
|
72
|
+
"- centralize settings",
|
|
73
|
+
"- move logic inside if branch",
|
|
39
74
|
].join("\n")
|
|
40
75
|
);
|
|
41
76
|
});
|
package/src/core/Metadata.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import { invariant } from "~/core/invariant";
|
|
2
2
|
import { safe_quote } from "~/core/safe_quote";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
type InputMetadataValues = {
|
|
5
|
+
id: string;
|
|
6
|
+
title?: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
type OutputMetadataValues = {
|
|
10
|
+
id: null | string;
|
|
11
|
+
title: null | string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export function write(message: string, values: InputMetadataValues) {
|
|
5
15
|
let result = message;
|
|
6
16
|
|
|
7
17
|
// escape double-quote for cli
|
|
@@ -10,23 +20,34 @@ export function write(message: string, stack_id: string) {
|
|
|
10
20
|
// remove any previous metadata lines
|
|
11
21
|
result = remove(result);
|
|
12
22
|
|
|
13
|
-
const line_list = [result, "", TEMPLATE.stack_id(
|
|
23
|
+
const line_list = [result, "", TEMPLATE.stack_id(values.id)];
|
|
24
|
+
|
|
25
|
+
if (values.title) {
|
|
26
|
+
line_list.push(TEMPLATE.group_title(values.title));
|
|
27
|
+
}
|
|
28
|
+
|
|
14
29
|
const new_message = line_list.join("\n");
|
|
15
30
|
|
|
16
31
|
return new_message;
|
|
17
32
|
}
|
|
18
33
|
|
|
19
|
-
export function read(message: string):
|
|
20
|
-
const
|
|
34
|
+
export function read(message: string): OutputMetadataValues {
|
|
35
|
+
const values: OutputMetadataValues = { id: null, title: null };
|
|
36
|
+
|
|
37
|
+
const match_id = message.match(RE.stack_id);
|
|
21
38
|
|
|
22
|
-
if (
|
|
23
|
-
|
|
39
|
+
if (match_id?.groups) {
|
|
40
|
+
values.id = match_id.groups["id"];
|
|
41
|
+
invariant(values.id, "id must exist");
|
|
24
42
|
}
|
|
25
43
|
|
|
26
|
-
const
|
|
27
|
-
|
|
44
|
+
const match_title = message.match(RE.group_title);
|
|
45
|
+
|
|
46
|
+
if (match_title?.groups) {
|
|
47
|
+
values.title = match_title.groups["title"];
|
|
48
|
+
}
|
|
28
49
|
|
|
29
|
-
return
|
|
50
|
+
return values;
|
|
30
51
|
}
|
|
31
52
|
|
|
32
53
|
export function remove(message: string) {
|
|
@@ -34,6 +55,7 @@ export function remove(message: string) {
|
|
|
34
55
|
|
|
35
56
|
// remove metadata
|
|
36
57
|
result = result.replace(new RegExp(RE.stack_id, "gmi"), "");
|
|
58
|
+
result = result.replace(new RegExp(RE.group_title, "gmi"), "");
|
|
37
59
|
|
|
38
60
|
result = result.trimEnd();
|
|
39
61
|
|
|
@@ -44,8 +66,13 @@ const TEMPLATE = {
|
|
|
44
66
|
stack_id(id: string) {
|
|
45
67
|
return `git-stack-id: ${id}`;
|
|
46
68
|
},
|
|
69
|
+
|
|
70
|
+
group_title(title: string) {
|
|
71
|
+
return `git-stack-title: ${title}`;
|
|
72
|
+
},
|
|
47
73
|
};
|
|
48
74
|
|
|
49
75
|
const RE = {
|
|
50
76
|
stack_id: new RegExp(TEMPLATE.stack_id("(?<id>[a-z0-9-+=]+)"), "i"),
|
|
77
|
+
group_title: new RegExp(TEMPLATE.group_title("(?<title>[^\\n^\\r]+)"), "i"),
|
|
51
78
|
};
|