better-commits 1.23.1 → 1.23.3
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/branch.js +628 -19
- package/dist/chunk-GAAS3VS3.js +922 -0
- package/dist/chunk-H5CLUQIL.js +313 -0
- package/dist/index.js +1122 -41
- package/dist/init.js +44 -1
- package/package.json +12 -4
- package/readme.md +4 -2
- package/.better-commits.json +0 -52
- package/.github/workflows/publish.yml +0 -34
- package/.github/workflows/test.yml +0 -27
- package/.prettierignore +0 -5
- package/.prettierrc +0 -1
- package/dist/chunk-43H72S6V.js +0 -1
- package/dist/chunk-B7AGSPP3.js +0 -261
- package/src/args.test.ts +0 -128
- package/src/args.ts +0 -125
- package/src/branch-args.test.ts +0 -75
- package/src/branch-args.ts +0 -107
- package/src/branch-help.ts +0 -125
- package/src/branch.ts +0 -97
- package/src/default-config-template.ts +0 -258
- package/src/git.ts +0 -60
- package/src/help.ts +0 -138
- package/src/index.test.ts +0 -7
- package/src/index.ts +0 -101
- package/src/init.test.ts +0 -123
- package/src/init.ts +0 -46
- package/src/prompts/autocomplete-multiselect.test.ts +0 -129
- package/src/prompts/autocomplete-multiselect.ts +0 -249
- package/src/prompts/branch-checkout.prompt.ts +0 -36
- package/src/prompts/branch-confirm.prompt.ts +0 -134
- package/src/prompts/branch-description.prompt.ts +0 -37
- package/src/prompts/branch-runnable.ts +0 -13
- package/src/prompts/branch-scope.prompt.ts +0 -59
- package/src/prompts/branch-ticket.prompt.ts +0 -41
- package/src/prompts/branch-type.prompt.ts +0 -46
- package/src/prompts/branch-user.prompt.ts +0 -50
- package/src/prompts/branch-version.prompt.ts +0 -41
- package/src/prompts/commit-body.prompt.ts +0 -57
- package/src/prompts/commit-confirm.prompt.ts +0 -119
- package/src/prompts/commit-footer.prompt.ts +0 -195
- package/src/prompts/commit-scope.prompt.ts +0 -91
- package/src/prompts/commit-status.prompt.ts +0 -78
- package/src/prompts/commit-ticket.prompt.ts +0 -82
- package/src/prompts/commit-title.prompt.ts +0 -98
- package/src/prompts/commit-type.prompt.ts +0 -96
- package/src/prompts/runnable.ts +0 -13
- package/src/utils/build-branch.test.ts +0 -159
- package/src/utils/build-branch.ts +0 -48
- package/src/utils/build-commit-string.test.ts +0 -253
- package/src/utils/build-commit-string.ts +0 -158
- package/src/utils/commit-title-size.ts +0 -24
- package/src/utils/infer.test.ts +0 -174
- package/src/utils/infer.ts +0 -160
- package/src/utils/messages.ts +0 -25
- package/src/utils/no-interactive-branch-validation.test.ts +0 -193
- package/src/utils/no-interactive-validation.test.ts +0 -174
- package/src/utils/no-interactive-validation.ts +0 -213
- package/src/utils.test.ts +0 -164
- package/src/utils.ts +0 -235
- package/src/valibot-consts.ts +0 -117
- package/src/valibot-state.test.ts +0 -57
- package/src/valibot-state.ts +0 -276
- package/tsconfig.json +0 -15
- package/tsup.config.ts +0 -12
- package/vitest.config.ts +0 -8
package/dist/branch.js
CHANGED
|
@@ -1,28 +1,637 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import {
|
|
3
|
+
create_strict_branch_state,
|
|
4
|
+
infer_scope_from_git,
|
|
5
|
+
infer_ticket_from_git,
|
|
6
|
+
infer_type_from_git,
|
|
7
|
+
optional_message
|
|
8
|
+
} from "./chunk-H5CLUQIL.js";
|
|
9
|
+
import {
|
|
10
|
+
BRANCH_ACTION_OPTIONS,
|
|
11
|
+
BranchState,
|
|
12
|
+
CUSTOM_SCOPE_KEY,
|
|
13
|
+
NOOP_PROMPT_CACHE,
|
|
14
|
+
get_git_root,
|
|
15
|
+
get_package_version,
|
|
16
|
+
get_value_from_cache,
|
|
17
|
+
load_setup,
|
|
18
|
+
set_value_cache
|
|
19
|
+
} from "./chunk-GAAS3VS3.js";
|
|
5
20
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
21
|
+
// src/branch.ts
|
|
22
|
+
import Configstore from "configstore";
|
|
23
|
+
import { chdir as chdir2 } from "process";
|
|
24
|
+
import { ValiError, parse as parse2 } from "valibot";
|
|
9
25
|
|
|
10
|
-
|
|
11
|
-
|
|
26
|
+
// src/prompts/branch-runnable.ts
|
|
27
|
+
var BranchRunnable = class {
|
|
28
|
+
constructor(config2, branch_state, prompt_cache) {
|
|
29
|
+
this.config = config2;
|
|
30
|
+
this.branch_state = branch_state;
|
|
31
|
+
this.prompt_cache = prompt_cache;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
12
34
|
|
|
13
|
-
|
|
14
|
-
|
|
35
|
+
// src/prompts/branch-checkout.prompt.ts
|
|
36
|
+
import * as p from "@clack/prompts";
|
|
37
|
+
var BranchCheckoutPrompt = class extends BranchRunnable {
|
|
38
|
+
async run() {
|
|
39
|
+
if (this.#is_enabled) {
|
|
40
|
+
const branch_or_worktree = await p.select({
|
|
41
|
+
message: this.#message,
|
|
42
|
+
initialValue: this.#initival_values,
|
|
43
|
+
options: BRANCH_ACTION_OPTIONS
|
|
44
|
+
});
|
|
45
|
+
if (p.isCancel(branch_or_worktree))
|
|
46
|
+
process.exit();
|
|
47
|
+
this.#post_run_effects(branch_or_worktree);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
get #message() {
|
|
51
|
+
return `Checkout a branch or create a worktree?`;
|
|
52
|
+
}
|
|
53
|
+
get #is_enabled() {
|
|
54
|
+
return this.config.worktrees.enable;
|
|
55
|
+
}
|
|
56
|
+
get #initival_values() {
|
|
57
|
+
return this.branch_state.checkout || this.config.branch_action_default;
|
|
58
|
+
}
|
|
59
|
+
#post_run_effects(value) {
|
|
60
|
+
this.branch_state.checkout = value;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
15
63
|
|
|
16
|
-
|
|
17
|
-
|
|
64
|
+
// src/prompts/branch-user.prompt.ts
|
|
65
|
+
import * as p2 from "@clack/prompts";
|
|
66
|
+
var BranchUserPrompt = class extends BranchRunnable {
|
|
67
|
+
async run() {
|
|
68
|
+
if (!this.#is_enabled)
|
|
69
|
+
return;
|
|
70
|
+
const user_name = await p2.text({
|
|
71
|
+
message: this.#message,
|
|
72
|
+
placeholder: "",
|
|
73
|
+
initialValue: this.#initial_value,
|
|
74
|
+
validate: (value) => this.#validate(value)
|
|
75
|
+
});
|
|
76
|
+
if (p2.isCancel(user_name))
|
|
77
|
+
process.exit(0);
|
|
78
|
+
this.#run_post_effects(user_name ?? "");
|
|
79
|
+
}
|
|
80
|
+
get #is_enabled() {
|
|
81
|
+
return this.config.branch_user.enable;
|
|
82
|
+
}
|
|
83
|
+
get #is_required() {
|
|
84
|
+
return this.config.branch_user.required;
|
|
85
|
+
}
|
|
86
|
+
get #message() {
|
|
87
|
+
return this.#is_required ? "Type your git username" : optional_message("Type your git username");
|
|
88
|
+
}
|
|
89
|
+
get #initial_value() {
|
|
90
|
+
return this.branch_state.user || get_value_from_cache(this.prompt_cache, "username");
|
|
91
|
+
}
|
|
92
|
+
#validate(value) {
|
|
93
|
+
if (this.#is_required && !value)
|
|
94
|
+
return "Please enter a username";
|
|
95
|
+
}
|
|
96
|
+
#run_post_effects(prompt_result) {
|
|
97
|
+
this.branch_state.user = prompt_result.replace(/\s+/g, "-").toLowerCase();
|
|
98
|
+
set_value_cache(this.prompt_cache, "username", this.branch_state.user);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
18
101
|
|
|
19
|
-
|
|
20
|
-
|
|
102
|
+
// src/prompts/branch-type.prompt.ts
|
|
103
|
+
import * as p3 from "@clack/prompts";
|
|
104
|
+
var BranchTypePrompt = class extends BranchRunnable {
|
|
105
|
+
async run() {
|
|
106
|
+
if (!this.#is_enabled)
|
|
107
|
+
return;
|
|
108
|
+
const prompt_type = this.config.branch_type.autocomplete ? p3.autocomplete : p3.select;
|
|
109
|
+
const branch_type = await prompt_type({
|
|
110
|
+
message: this.#message,
|
|
111
|
+
initialValue: this.#initial_value,
|
|
112
|
+
options: this.#options
|
|
113
|
+
});
|
|
114
|
+
if (p3.isCancel(branch_type))
|
|
115
|
+
process.exit(0);
|
|
116
|
+
this.#run_post_effects(branch_type);
|
|
117
|
+
}
|
|
118
|
+
get #is_enabled() {
|
|
119
|
+
return this.config.branch_type.enable;
|
|
120
|
+
}
|
|
121
|
+
get #message() {
|
|
122
|
+
return "Select a branch type";
|
|
123
|
+
}
|
|
124
|
+
get #initial_value() {
|
|
125
|
+
return this.branch_state.type || this.config.commit_type.initial_value;
|
|
126
|
+
}
|
|
127
|
+
get #options() {
|
|
128
|
+
return this.config.commit_type.options;
|
|
129
|
+
}
|
|
130
|
+
#run_post_effects(prompt_result) {
|
|
131
|
+
this.branch_state.type = prompt_result;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
21
134
|
|
|
22
|
-
|
|
23
|
-
|
|
135
|
+
// src/prompts/branch-scope.prompt.ts
|
|
136
|
+
import * as p4 from "@clack/prompts";
|
|
137
|
+
var BranchScopePrompt = class extends BranchRunnable {
|
|
138
|
+
async run() {
|
|
139
|
+
if (!this.#is_enabled)
|
|
140
|
+
return;
|
|
141
|
+
const prompt_type = this.config.branch_scope.autocomplete ? p4.autocomplete : p4.select;
|
|
142
|
+
const branch_scope = await prompt_type({
|
|
143
|
+
message: this.#message,
|
|
144
|
+
initialValue: this.#initial_value,
|
|
145
|
+
options: this.#options
|
|
146
|
+
});
|
|
147
|
+
if (p4.isCancel(branch_scope))
|
|
148
|
+
process.exit(0);
|
|
149
|
+
await this.#run_post_effects(branch_scope);
|
|
150
|
+
}
|
|
151
|
+
get #is_enabled() {
|
|
152
|
+
return this.config.branch_scope.enable;
|
|
153
|
+
}
|
|
154
|
+
get #message() {
|
|
155
|
+
return "Select a branch scope";
|
|
156
|
+
}
|
|
157
|
+
get #initial_value() {
|
|
158
|
+
return this.branch_state.scope || this.config.commit_scope.initial_value;
|
|
159
|
+
}
|
|
160
|
+
get #options() {
|
|
161
|
+
return this.config.commit_scope.options;
|
|
162
|
+
}
|
|
163
|
+
get #custom_scope_enabled() {
|
|
164
|
+
return this.config.commit_scope.custom_scope;
|
|
165
|
+
}
|
|
166
|
+
async #run_post_effects(prompt_result) {
|
|
167
|
+
let branch_scope_value = prompt_result;
|
|
168
|
+
if (branch_scope_value === CUSTOM_SCOPE_KEY && this.#custom_scope_enabled) {
|
|
169
|
+
const branch_scope = await p4.text({
|
|
170
|
+
message: "Write a custom scope",
|
|
171
|
+
placeholder: ""
|
|
172
|
+
});
|
|
173
|
+
if (p4.isCancel(branch_scope))
|
|
174
|
+
process.exit(0);
|
|
175
|
+
branch_scope_value = branch_scope ?? "";
|
|
176
|
+
}
|
|
177
|
+
this.branch_state.scope = branch_scope_value;
|
|
178
|
+
}
|
|
179
|
+
};
|
|
24
180
|
|
|
25
|
-
|
|
26
|
-
|
|
181
|
+
// src/prompts/branch-ticket.prompt.ts
|
|
182
|
+
import * as p5 from "@clack/prompts";
|
|
183
|
+
var BranchTicketPrompt = class extends BranchRunnable {
|
|
184
|
+
async run() {
|
|
185
|
+
if (!this.#is_enabled)
|
|
186
|
+
return;
|
|
187
|
+
const ticket = await p5.text({
|
|
188
|
+
message: this.#message,
|
|
189
|
+
placeholder: "",
|
|
190
|
+
validate: (value) => this.#validate(value),
|
|
191
|
+
initialValue: this.branch_state.ticket
|
|
192
|
+
});
|
|
193
|
+
if (p5.isCancel(ticket))
|
|
194
|
+
process.exit(0);
|
|
195
|
+
this.#run_post_effects(ticket ?? "");
|
|
196
|
+
}
|
|
197
|
+
get #is_enabled() {
|
|
198
|
+
return this.config.branch_ticket.enable;
|
|
199
|
+
}
|
|
200
|
+
get #is_required() {
|
|
201
|
+
return this.config.branch_ticket.required;
|
|
202
|
+
}
|
|
203
|
+
get #message() {
|
|
204
|
+
return this.#is_required ? "Type ticket / issue number" : optional_message("Type ticket / issue number");
|
|
205
|
+
}
|
|
206
|
+
#validate(value) {
|
|
207
|
+
if (this.#is_required && !value)
|
|
208
|
+
return "Please enter a ticket / issue";
|
|
209
|
+
}
|
|
210
|
+
#run_post_effects(prompt_result) {
|
|
211
|
+
this.branch_state.ticket = prompt_result;
|
|
212
|
+
}
|
|
213
|
+
};
|
|
27
214
|
|
|
28
|
-
|
|
215
|
+
// src/prompts/branch-version.prompt.ts
|
|
216
|
+
import * as p6 from "@clack/prompts";
|
|
217
|
+
var BranchVersionPrompt = class extends BranchRunnable {
|
|
218
|
+
async run() {
|
|
219
|
+
if (!this.#is_enabled)
|
|
220
|
+
return;
|
|
221
|
+
const version = await p6.text({
|
|
222
|
+
message: this.#message,
|
|
223
|
+
placeholder: "",
|
|
224
|
+
validate: (value) => this.#validate(value),
|
|
225
|
+
initialValue: this.branch_state.version
|
|
226
|
+
});
|
|
227
|
+
if (p6.isCancel(version))
|
|
228
|
+
process.exit(0);
|
|
229
|
+
this.#run_post_effects(version ?? "");
|
|
230
|
+
}
|
|
231
|
+
get #is_enabled() {
|
|
232
|
+
return this.config.branch_version.enable;
|
|
233
|
+
}
|
|
234
|
+
get #is_required() {
|
|
235
|
+
return this.config.branch_version.required;
|
|
236
|
+
}
|
|
237
|
+
get #message() {
|
|
238
|
+
return this.#is_required ? "Type version number" : optional_message("Type version number");
|
|
239
|
+
}
|
|
240
|
+
#validate(value) {
|
|
241
|
+
if (this.#is_required && !value)
|
|
242
|
+
return "Please enter a version";
|
|
243
|
+
}
|
|
244
|
+
#run_post_effects(prompt_result) {
|
|
245
|
+
this.branch_state.version = prompt_result;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// src/prompts/branch-description.prompt.ts
|
|
250
|
+
import * as p7 from "@clack/prompts";
|
|
251
|
+
var BranchDescriptionPrompt = class extends BranchRunnable {
|
|
252
|
+
async run() {
|
|
253
|
+
const description = await p7.text({
|
|
254
|
+
message: this.#message,
|
|
255
|
+
placeholder: "",
|
|
256
|
+
validate: (value) => this.#validate(value),
|
|
257
|
+
initialValue: this.branch_state.description
|
|
258
|
+
});
|
|
259
|
+
if (p7.isCancel(description))
|
|
260
|
+
process.exit(0);
|
|
261
|
+
this.#run_post_effects(description ?? "");
|
|
262
|
+
}
|
|
263
|
+
get #message() {
|
|
264
|
+
return "Type a short description";
|
|
265
|
+
}
|
|
266
|
+
get #max_length() {
|
|
267
|
+
return this.config.branch_description.max_length;
|
|
268
|
+
}
|
|
269
|
+
#validate(value) {
|
|
270
|
+
if (!value)
|
|
271
|
+
return "Please enter a description";
|
|
272
|
+
if (value.length > this.#max_length) {
|
|
273
|
+
return `Exceeded max length. Description max [${this.#max_length}]`;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
#run_post_effects(prompt_result) {
|
|
277
|
+
this.branch_state.description = prompt_result.replace(/\s+/g, "-").toLowerCase();
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
// src/prompts/branch-confirm.prompt.ts
|
|
282
|
+
import * as p8 from "@clack/prompts";
|
|
283
|
+
import { execSync } from "child_process";
|
|
284
|
+
import color from "picocolors";
|
|
285
|
+
import { chdir } from "process";
|
|
286
|
+
|
|
287
|
+
// src/branch-args.ts
|
|
288
|
+
import { parse } from "@bomb.sh/args";
|
|
289
|
+
var BRANCH_OPTIONS = [
|
|
290
|
+
"user",
|
|
291
|
+
"type",
|
|
292
|
+
"scope",
|
|
293
|
+
"description",
|
|
294
|
+
"ticket",
|
|
295
|
+
"branch-version",
|
|
296
|
+
"checkout"
|
|
297
|
+
];
|
|
298
|
+
var GIT_OPTIONS = ["git-dir", "work-tree"];
|
|
299
|
+
var BOOLEAN_FLAGS = [
|
|
300
|
+
"interactive",
|
|
301
|
+
"dry-run",
|
|
302
|
+
"help",
|
|
303
|
+
"version"
|
|
304
|
+
];
|
|
305
|
+
var BranchFlags = class {
|
|
306
|
+
#runtime;
|
|
307
|
+
constructor(runtime) {
|
|
308
|
+
this.#runtime = runtime;
|
|
309
|
+
}
|
|
310
|
+
get interactive() {
|
|
311
|
+
return !this.#runtime.no_interactive;
|
|
312
|
+
}
|
|
313
|
+
get dry_run() {
|
|
314
|
+
return this.#runtime.dry_run;
|
|
315
|
+
}
|
|
316
|
+
get help() {
|
|
317
|
+
return this.#runtime.help;
|
|
318
|
+
}
|
|
319
|
+
get version() {
|
|
320
|
+
return this.#runtime.version;
|
|
321
|
+
}
|
|
322
|
+
get git_args() {
|
|
323
|
+
return this.#runtime.git_args;
|
|
324
|
+
}
|
|
325
|
+
get branch_state() {
|
|
326
|
+
return this.#runtime.branch_state;
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
var branch_flags = new BranchFlags(
|
|
330
|
+
parse_branch_runtime_flags(process.argv.slice(2))
|
|
331
|
+
);
|
|
332
|
+
function parse_branch_runtime_flags(argv) {
|
|
333
|
+
const parsed = parse(argv, {
|
|
334
|
+
alias: { h: "help", v: "version" },
|
|
335
|
+
boolean: BOOLEAN_FLAGS,
|
|
336
|
+
string: [...BRANCH_OPTIONS, ...GIT_OPTIONS]
|
|
337
|
+
});
|
|
338
|
+
const branch_state = {};
|
|
339
|
+
BRANCH_OPTIONS.forEach((value) => {
|
|
340
|
+
const cli_value = parsed[value];
|
|
341
|
+
if (cli_value) {
|
|
342
|
+
const str = value === "branch-version" ? "version" : value.replace("-", "_");
|
|
343
|
+
if (str === "checkout")
|
|
344
|
+
branch_state[str] = cli_value ?? "branch";
|
|
345
|
+
else if (str === "description")
|
|
346
|
+
branch_state[str] = cli_value.replace(/\s+/g, "-").toLowerCase();
|
|
347
|
+
else
|
|
348
|
+
branch_state[str] = cli_value;
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
return {
|
|
352
|
+
help: parsed["help"] === true,
|
|
353
|
+
version: parsed["version"] === true,
|
|
354
|
+
git_args: get_git_args(parsed["git-dir"], parsed["work-tree"]),
|
|
355
|
+
no_interactive: parsed["interactive"] === false,
|
|
356
|
+
dry_run: parsed["dry-run"] === true,
|
|
357
|
+
branch_state
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
function get_git_args(git_dir, work_tree) {
|
|
361
|
+
return `${git_dir ? `--git-dir=${git_dir}` : ""} ${work_tree ? `--work-tree=${work_tree}` : ""}`.trim();
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// src/utils/build-branch.ts
|
|
365
|
+
function build_branch(branch, config2) {
|
|
366
|
+
let res = "";
|
|
367
|
+
config2.branch_order.forEach((b) => {
|
|
368
|
+
const config_key = `branch_${b}`;
|
|
369
|
+
if (branch[b])
|
|
370
|
+
res += branch[b] + config2[config_key].separator;
|
|
371
|
+
});
|
|
372
|
+
if (res.endsWith("-") || res.endsWith("/") || res.endsWith("_")) {
|
|
373
|
+
return res.slice(0, -1).trim();
|
|
374
|
+
}
|
|
375
|
+
return res.trim();
|
|
376
|
+
}
|
|
377
|
+
function build_worktree_path(branch_state, config2, git_root) {
|
|
378
|
+
const repo_name = git_root.split("/").pop() || "repo";
|
|
379
|
+
let worktree_name = config2.worktrees.folder_template;
|
|
380
|
+
worktree_name = worktree_name.replace("{{repo_name}}", repo_name).replace("{{branch_description}}", branch_state.description).replace("{{user}}", branch_state.user || "").replace("{{type}}", branch_state.type || "").replace("{{scope}}", branch_state.scope || "").replace("{{ticket}}", branch_state.ticket || "").replace("{{version}}", branch_state.version || "");
|
|
381
|
+
worktree_name = worktree_name.replace(/\s/g, "").replace(/--+/g, "-").replace(/^-+|-+$/g, "");
|
|
382
|
+
const base_path = config2.worktrees.base_path;
|
|
383
|
+
return `${base_path}${base_path.endsWith("/") ? "" : "/"}${worktree_name}`;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// src/prompts/branch-confirm.prompt.ts
|
|
387
|
+
var BranchConfirmPrompt = class extends BranchRunnable {
|
|
388
|
+
async run() {
|
|
389
|
+
this.#run_pre_commands();
|
|
390
|
+
this.#run_checkout();
|
|
391
|
+
this.#run_post_commands();
|
|
392
|
+
}
|
|
393
|
+
get #is_worktree() {
|
|
394
|
+
return this.branch_state.checkout === "worktree";
|
|
395
|
+
}
|
|
396
|
+
get #pre_commands() {
|
|
397
|
+
return this.#is_worktree ? this.config.worktree_pre_commands : this.config.branch_pre_commands;
|
|
398
|
+
}
|
|
399
|
+
get #post_commands() {
|
|
400
|
+
return this.#is_worktree ? this.config.worktree_post_commands : this.config.branch_post_commands;
|
|
401
|
+
}
|
|
402
|
+
get #branch_name() {
|
|
403
|
+
return build_branch(this.branch_state, this.config);
|
|
404
|
+
}
|
|
405
|
+
#run_pre_commands() {
|
|
406
|
+
this.#run_commands(
|
|
407
|
+
this.#pre_commands,
|
|
408
|
+
"Something went wrong when executing pre-commands: "
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
#run_checkout() {
|
|
412
|
+
const branch_name = this.#branch_name;
|
|
413
|
+
const branch_flag = this.#verify_branch_name(branch_name);
|
|
414
|
+
if (!this.#is_worktree) {
|
|
415
|
+
const command = `git ${branch_flags.git_args} checkout ${branch_flag} ${branch_name}`;
|
|
416
|
+
if (branch_flags.dry_run) {
|
|
417
|
+
this.#log_dry_run_command(command);
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
try {
|
|
421
|
+
execSync(command, {
|
|
422
|
+
stdio: "inherit"
|
|
423
|
+
});
|
|
424
|
+
p8.log.info(
|
|
425
|
+
`Switched to a new branch '${color.bgGreen(
|
|
426
|
+
" " + color.black(branch_name) + " "
|
|
427
|
+
)}'`
|
|
428
|
+
);
|
|
429
|
+
} catch (err) {
|
|
430
|
+
process.exit(0);
|
|
431
|
+
}
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
try {
|
|
435
|
+
const worktree_name = build_worktree_path(
|
|
436
|
+
this.branch_state,
|
|
437
|
+
this.config,
|
|
438
|
+
get_git_root(branch_flags.git_args)
|
|
439
|
+
);
|
|
440
|
+
const command = `git ${branch_flags.git_args} worktree add ${worktree_name} ${branch_flag} ${branch_name}`;
|
|
441
|
+
if (branch_flags.dry_run) {
|
|
442
|
+
this.#log_dry_run_command(command);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
execSync(command, {
|
|
446
|
+
stdio: "inherit"
|
|
447
|
+
});
|
|
448
|
+
p8.log.info(
|
|
449
|
+
`Created a new worktree ${color.bgGreen(
|
|
450
|
+
" " + color.black(worktree_name) + " "
|
|
451
|
+
)}, checked out branch ${color.bgGreen(
|
|
452
|
+
" " + color.black(branch_name) + " "
|
|
453
|
+
)}`
|
|
454
|
+
);
|
|
455
|
+
p8.log.info(
|
|
456
|
+
color.bgMagenta(color.black(` cd ${worktree_name} `)) + " to navigate to your new worktree"
|
|
457
|
+
);
|
|
458
|
+
chdir(worktree_name);
|
|
459
|
+
} catch (err) {
|
|
460
|
+
process.exit(0);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
#run_post_commands() {
|
|
464
|
+
this.#run_commands(
|
|
465
|
+
this.#post_commands,
|
|
466
|
+
"Something went wrong when executing post-commands: "
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
#run_commands(commands, error_message) {
|
|
470
|
+
commands.forEach((command) => {
|
|
471
|
+
if (branch_flags.dry_run) {
|
|
472
|
+
this.#log_dry_run_command(command);
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
try {
|
|
476
|
+
execSync(command, { stdio: "inherit" });
|
|
477
|
+
} catch (err) {
|
|
478
|
+
p8.log.error(error_message + err);
|
|
479
|
+
process.exit(0);
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
#log_dry_run_command(command) {
|
|
484
|
+
p8.log.info(`Dry run: ${command}`);
|
|
485
|
+
}
|
|
486
|
+
#verify_branch_name(branch_name) {
|
|
487
|
+
let branch_flag = "";
|
|
488
|
+
try {
|
|
489
|
+
execSync(`git ${branch_flags.git_args} show-ref ${branch_name}`, {
|
|
490
|
+
encoding: "utf-8"
|
|
491
|
+
});
|
|
492
|
+
p8.log.warning(
|
|
493
|
+
color.yellow(
|
|
494
|
+
`${branch_name} already exists! Checking out existing branch.`
|
|
495
|
+
)
|
|
496
|
+
);
|
|
497
|
+
} catch (err) {
|
|
498
|
+
branch_flag = "-b";
|
|
499
|
+
}
|
|
500
|
+
return branch_flag;
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
// src/branch-help.ts
|
|
505
|
+
import { execSync as execSync2 } from "child_process";
|
|
506
|
+
import color2 from "picocolors";
|
|
507
|
+
var CLI_FLAG_DEFINITIONS = {
|
|
508
|
+
"--interactive": "Run in interactive prompt mode (default behavior).",
|
|
509
|
+
"--dry-run": "Print branch commands without creating a branch or worktree.",
|
|
510
|
+
"--help": "Show help information and exit."
|
|
511
|
+
};
|
|
512
|
+
var BRANCH_FLAG_DEFINITIONS = {
|
|
513
|
+
"--user": "Set branch username segment.",
|
|
514
|
+
"--type": "Set branch type (for example feat, fix, docs).",
|
|
515
|
+
"--scope": "Set branch scope segment.",
|
|
516
|
+
"--description": "Set branch description segment.",
|
|
517
|
+
"--ticket": "Set branch ticket/issue segment.",
|
|
518
|
+
"--branch-version": "Set branch version segment.",
|
|
519
|
+
"--checkout": "Choose branch or worktree checkout mode."
|
|
520
|
+
};
|
|
521
|
+
var GIT_FLAG_DEFINITIONS = {
|
|
522
|
+
"--git-dir": "Set the path to the .git directory.",
|
|
523
|
+
"--work-tree": "Set the path to the working tree root."
|
|
524
|
+
};
|
|
525
|
+
function to_definition_lines(definitions) {
|
|
526
|
+
const description_column = 26;
|
|
527
|
+
const minimum_spacing = 2;
|
|
528
|
+
const indent = " ";
|
|
529
|
+
return Object.entries(definitions).map(([name, description]) => {
|
|
530
|
+
const spaces = Math.max(
|
|
531
|
+
minimum_spacing,
|
|
532
|
+
description_column - name.length
|
|
533
|
+
);
|
|
534
|
+
return `${indent}${name}${" ".repeat(spaces)}${description}`;
|
|
535
|
+
}).join("\n");
|
|
536
|
+
}
|
|
537
|
+
function print_help_text(config2, config_source2) {
|
|
538
|
+
const version = get_package_version();
|
|
539
|
+
let branch = "(none)";
|
|
540
|
+
try {
|
|
541
|
+
branch = execSync2(`git ${branch_flags.git_args} branch --show-current`, {
|
|
542
|
+
stdio: "pipe"
|
|
543
|
+
}).toString().trim() || "(none)";
|
|
544
|
+
} catch {
|
|
545
|
+
}
|
|
546
|
+
const inferred_type = infer_type_from_git(config2.commit_type.options, branch_flags.git_args) || "Unknown";
|
|
547
|
+
const inferred_ticket = config2.check_ticket.infer_ticket ? infer_ticket_from_git(
|
|
548
|
+
{
|
|
549
|
+
append_hashtag: config2.check_ticket.append_hashtag,
|
|
550
|
+
prepend_hashtag: config2.check_ticket.prepend_hashtag
|
|
551
|
+
},
|
|
552
|
+
branch_flags.git_args
|
|
553
|
+
) || "Unknown" : "Infer Disabled";
|
|
554
|
+
const inferred_scope = config2.commit_scope.infer_scope_from_branch ? infer_scope_from_git(
|
|
555
|
+
config2.commit_scope.options,
|
|
556
|
+
branch_flags.git_args
|
|
557
|
+
) || "Unknown" : "Infer Disabled";
|
|
558
|
+
const types = config2.commit_type.options.map((option) => option.value).join(", ").trim();
|
|
559
|
+
const scopes = config2.commit_scope.options.map((option) => option.value).join(", ").trim();
|
|
560
|
+
const cli_flags = to_definition_lines(CLI_FLAG_DEFINITIONS);
|
|
561
|
+
const git_flags = to_definition_lines(GIT_FLAG_DEFINITIONS);
|
|
562
|
+
const branch_flags_help = to_definition_lines(BRANCH_FLAG_DEFINITIONS);
|
|
563
|
+
console.log(`
|
|
564
|
+
${color2.green("\uF489 better-branch")} ${color2.gray("v" + version)}
|
|
565
|
+
|
|
566
|
+
${color2.gray("BRANCH")}
|
|
567
|
+
${branch}
|
|
568
|
+
${color2.gray("Type")} ${color2.blue(inferred_type)} ${color2.gray("\xB7")} ${color2.gray("Scope")} ${color2.cyan(inferred_scope)} ${color2.gray("\xB7")} ${color2.gray("Ticket")} ${color2.magenta(inferred_ticket)}
|
|
569
|
+
|
|
570
|
+
${color2.gray("CONFIGURATION")}
|
|
571
|
+
${config_source2}
|
|
572
|
+
|
|
573
|
+
${color2.gray("Types")}
|
|
574
|
+
${types}
|
|
575
|
+
|
|
576
|
+
${color2.gray("Scopes")}
|
|
577
|
+
${scopes}
|
|
578
|
+
|
|
579
|
+
${color2.gray("CLI FLAGS")}
|
|
580
|
+
${cli_flags}
|
|
581
|
+
|
|
582
|
+
${color2.gray("Branch Flags")}
|
|
583
|
+
${branch_flags_help}
|
|
584
|
+
|
|
585
|
+
${color2.gray("Git Flags (Advanced)")}
|
|
586
|
+
${git_flags}
|
|
587
|
+
|
|
588
|
+
`);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// src/branch.ts
|
|
592
|
+
import * as p9 from "@clack/prompts";
|
|
593
|
+
var promptCtors = [
|
|
594
|
+
BranchCheckoutPrompt,
|
|
595
|
+
BranchUserPrompt,
|
|
596
|
+
BranchTypePrompt,
|
|
597
|
+
BranchTicketPrompt,
|
|
598
|
+
BranchScopePrompt,
|
|
599
|
+
BranchVersionPrompt,
|
|
600
|
+
BranchDescriptionPrompt,
|
|
601
|
+
BranchConfirmPrompt
|
|
602
|
+
];
|
|
603
|
+
var { config, config_source } = load_setup(
|
|
604
|
+
" better-branch ",
|
|
605
|
+
branch_flags.git_args
|
|
606
|
+
);
|
|
607
|
+
main(config, config_source);
|
|
608
|
+
async function main(config2, config_source2) {
|
|
609
|
+
chdir2(get_git_root(branch_flags.git_args));
|
|
610
|
+
if (branch_flags.version) {
|
|
611
|
+
const version = get_package_version();
|
|
612
|
+
p9.log.step("Better Commits v" + version);
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
if (branch_flags.help) {
|
|
616
|
+
print_help_text(config2, config_source2);
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
const branch_state = parse2(BranchState, branch_flags.branch_state);
|
|
620
|
+
if (!branch_flags.interactive) {
|
|
621
|
+
try {
|
|
622
|
+
parse2(create_strict_branch_state(config2), branch_state);
|
|
623
|
+
} catch (err) {
|
|
624
|
+
if (err instanceof ValiError) {
|
|
625
|
+
p9.log.error(`Invalid branch input: ${err.message}`);
|
|
626
|
+
} else {
|
|
627
|
+
p9.log.error(`Failed to validate branch input: ${err}`);
|
|
628
|
+
}
|
|
629
|
+
process.exit(0);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
const prompt_cache = config2.cache_last_value ? new Configstore("better-commits") : NOOP_PROMPT_CACHE;
|
|
633
|
+
const prompts_to_run = branch_flags.interactive ? promptCtors : [BranchConfirmPrompt];
|
|
634
|
+
for (const Prompt of prompts_to_run) {
|
|
635
|
+
await new Prompt(config2, branch_state, prompt_cache).run();
|
|
636
|
+
}
|
|
637
|
+
}
|