better-commits 1.19.0 → 1.20.0-cli-flags
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/.better-commits.json +4 -0
- package/.github/workflows/test.yml +27 -0
- package/.opencode/package-lock.json +115 -0
- package/.opencode/plans/cli-args.md +182 -0
- package/.svelte-kit/ambient.d.ts +289 -0
- package/.svelte-kit/generated/client/app.js +28 -0
- package/.svelte-kit/generated/client/matchers.js +1 -0
- package/.svelte-kit/generated/client/nodes/0.js +1 -0
- package/.svelte-kit/generated/client/nodes/1.js +1 -0
- package/.svelte-kit/tsconfig.json +49 -0
- package/0001-feat-branch-124-update-worktrees-feature.patch +316 -0
- package/dist/branch.js +27 -1
- package/dist/chunk-OFJCRS3N.js +4 -0
- package/dist/chunk-SIF4LZUS.js +1 -0
- package/dist/index.js +44 -19
- package/dist/init.js +1 -1
- package/docs/ai-skills.yaml +48 -0
- package/docs/clack.md +143 -0
- package/docs/valibot.md +228 -0
- package/package.json +12 -9
- package/readme.md +18 -2
- package/src/args.test.ts +102 -0
- package/src/args.ts +101 -7
- package/src/branch-args.test.ts +72 -0
- package/src/branch-args.ts +106 -0
- package/src/branch-help.ts +114 -0
- package/src/branch.ts +67 -238
- package/src/help.ts +131 -0
- package/src/index.test.ts +7 -0
- package/src/index.ts +73 -492
- package/src/prompts/branch-checkout.prompt.ts +36 -0
- package/src/prompts/branch-confirm.prompt.ts +134 -0
- package/src/prompts/branch-description.prompt.ts +37 -0
- package/src/prompts/branch-runnable.ts +13 -0
- package/src/prompts/branch-ticket.prompt.ts +41 -0
- package/src/prompts/branch-type.prompt.ts +43 -0
- package/src/prompts/branch-user.prompt.ts +50 -0
- package/src/prompts/branch-version.prompt.ts +41 -0
- package/src/prompts/commit-body.prompt.ts +57 -0
- package/src/prompts/commit-confirm.prompt.ts +119 -0
- package/src/prompts/commit-footer.prompt.ts +195 -0
- package/src/prompts/commit-scope.prompt.ts +73 -0
- package/src/prompts/commit-status.prompt.ts +75 -0
- package/src/prompts/commit-ticket.prompt.ts +82 -0
- package/src/prompts/commit-title.prompt.ts +98 -0
- package/src/prompts/commit-type.prompt.ts +93 -0
- package/src/prompts/runnable.ts +13 -0
- package/src/utils/build-branch.test.ts +141 -0
- package/src/utils/build-branch.ts +46 -0
- package/src/utils/build-commit-string.test.ts +253 -0
- package/src/utils/build-commit-string.ts +158 -0
- package/src/utils/commit-title-size.ts +24 -0
- package/src/utils/infer.test.ts +83 -0
- package/src/utils/infer.ts +114 -0
- package/src/utils/messages.ts +25 -0
- package/src/utils/no-interactive-branch-validation.test.ts +170 -0
- package/src/utils/no-interactive-validation.test.ts +174 -0
- package/src/utils/no-interactive-validation.ts +190 -0
- package/src/utils.ts +59 -66
- package/src/valibot-consts.ts +2 -2
- package/src/valibot-state.test.ts +48 -0
- package/src/valibot-state.ts +133 -130
- package/tsconfig.json +3 -2
- package/vitest.config.ts +8 -0
- package/dist/chunk-K2RPF2JY.js +0 -4
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import color from "picocolors";
|
|
4
|
+
import { chdir } from "process";
|
|
5
|
+
import { branch_flags } from "../branch-args";
|
|
6
|
+
import { get_git_root } from "../utils";
|
|
7
|
+
import { build_branch, build_worktree_path } from "../utils/build-branch";
|
|
8
|
+
import { BranchRunnable } from "./branch-runnable";
|
|
9
|
+
|
|
10
|
+
export class BranchConfirmPrompt extends BranchRunnable {
|
|
11
|
+
async run(): Promise<void> {
|
|
12
|
+
this.#run_pre_commands();
|
|
13
|
+
this.#run_checkout();
|
|
14
|
+
this.#run_post_commands();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get #is_worktree(): boolean {
|
|
18
|
+
return this.branch_state.checkout === "worktree";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get #pre_commands(): string[] {
|
|
22
|
+
return this.#is_worktree
|
|
23
|
+
? this.config.worktree_pre_commands
|
|
24
|
+
: this.config.branch_pre_commands;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get #post_commands(): string[] {
|
|
28
|
+
return this.#is_worktree
|
|
29
|
+
? this.config.worktree_post_commands
|
|
30
|
+
: this.config.branch_post_commands;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get #branch_name(): string {
|
|
34
|
+
return build_branch(this.branch_state, this.config);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
#run_pre_commands(): void {
|
|
38
|
+
this.#run_commands(
|
|
39
|
+
this.#pre_commands,
|
|
40
|
+
"Something went wrong when executing pre-commands: ",
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#run_checkout(): void {
|
|
45
|
+
const branch_name = this.#branch_name;
|
|
46
|
+
const branch_flag = this.#verify_branch_name(branch_name);
|
|
47
|
+
|
|
48
|
+
if (!this.#is_worktree) {
|
|
49
|
+
try {
|
|
50
|
+
execSync(
|
|
51
|
+
`git ${branch_flags.git_args} checkout ${branch_flag} ${branch_name}`,
|
|
52
|
+
{
|
|
53
|
+
stdio: "inherit",
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
p.log.info(
|
|
57
|
+
`Switched to a new branch '${color.bgGreen(
|
|
58
|
+
" " + color.black(branch_name) + " ",
|
|
59
|
+
)}'`,
|
|
60
|
+
);
|
|
61
|
+
} catch (err) {
|
|
62
|
+
process.exit(0);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const worktree_name = build_worktree_path(
|
|
70
|
+
this.branch_state,
|
|
71
|
+
this.config,
|
|
72
|
+
get_git_root(branch_flags.git_args),
|
|
73
|
+
);
|
|
74
|
+
execSync(
|
|
75
|
+
`git ${branch_flags.git_args} worktree add ${worktree_name} ${branch_flag} ${branch_name}`,
|
|
76
|
+
{
|
|
77
|
+
stdio: "inherit",
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
p.log.info(
|
|
81
|
+
`Created a new worktree ${color.bgGreen(
|
|
82
|
+
" " + color.black(worktree_name) + " ",
|
|
83
|
+
)}, checked out branch ${color.bgGreen(
|
|
84
|
+
" " + color.black(branch_name) + " ",
|
|
85
|
+
)}`,
|
|
86
|
+
);
|
|
87
|
+
p.log.info(
|
|
88
|
+
color.bgMagenta(color.black(` cd ${worktree_name} `)) +
|
|
89
|
+
" to navigate to your new worktree",
|
|
90
|
+
);
|
|
91
|
+
chdir(worktree_name);
|
|
92
|
+
} catch (err) {
|
|
93
|
+
process.exit(0);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
#run_post_commands(): void {
|
|
98
|
+
this.#run_commands(
|
|
99
|
+
this.#post_commands,
|
|
100
|
+
"Something went wrong when executing post-commands: ",
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
#run_commands(commands: string[], error_message: string): void {
|
|
105
|
+
commands.forEach((command) => {
|
|
106
|
+
try {
|
|
107
|
+
execSync(command, { stdio: "inherit" });
|
|
108
|
+
} catch (err) {
|
|
109
|
+
p.log.error(error_message + err);
|
|
110
|
+
process.exit(0);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
#verify_branch_name(branch_name: string): string {
|
|
116
|
+
// TODO: There has to be a better way 🤦
|
|
117
|
+
let branch_flag = "";
|
|
118
|
+
try {
|
|
119
|
+
execSync(`git ${branch_flags.git_args} show-ref ${branch_name}`, {
|
|
120
|
+
encoding: "utf-8",
|
|
121
|
+
});
|
|
122
|
+
p.log.warning(
|
|
123
|
+
color.yellow(
|
|
124
|
+
`${branch_name} already exists! Checking out existing branch.`,
|
|
125
|
+
),
|
|
126
|
+
);
|
|
127
|
+
} catch (err) {
|
|
128
|
+
// Branch does not exist
|
|
129
|
+
branch_flag = "-b";
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return branch_flag;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { BranchRunnable } from "./branch-runnable";
|
|
3
|
+
|
|
4
|
+
export class BranchDescriptionPrompt extends BranchRunnable {
|
|
5
|
+
async run(): Promise<void> {
|
|
6
|
+
const description = await p.text({
|
|
7
|
+
message: this.#message,
|
|
8
|
+
placeholder: "",
|
|
9
|
+
validate: (value) => this.#validate(value),
|
|
10
|
+
initialValue: this.branch_state.description,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
if (p.isCancel(description)) process.exit(0);
|
|
14
|
+
this.#run_post_effects(description ?? "");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get #message(): string {
|
|
18
|
+
return "Type a short description";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get #max_length(): number {
|
|
22
|
+
return this.config.branch_description.max_length;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#validate(value: string | undefined): string | undefined {
|
|
26
|
+
if (!value) return "Please enter a description";
|
|
27
|
+
if (value.length > this.#max_length) {
|
|
28
|
+
return `Exceeded max length. Description max [${this.#max_length}]`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
#run_post_effects(prompt_result: string): void {
|
|
33
|
+
this.branch_state.description = prompt_result
|
|
34
|
+
.replace(/\s+/g, "-")
|
|
35
|
+
.toLowerCase();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { InferOutput } from "valibot";
|
|
2
|
+
import { BranchState, Config } from "../valibot-state";
|
|
3
|
+
import Configstore from "configstore";
|
|
4
|
+
|
|
5
|
+
export abstract class BranchRunnable {
|
|
6
|
+
constructor(
|
|
7
|
+
protected config: InferOutput<typeof Config>,
|
|
8
|
+
protected branch_state: InferOutput<typeof BranchState>,
|
|
9
|
+
protected prompt_cache: Configstore,
|
|
10
|
+
) {}
|
|
11
|
+
|
|
12
|
+
abstract run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { optional_message } from "../utils/messages";
|
|
3
|
+
import { BranchRunnable } from "./branch-runnable";
|
|
4
|
+
|
|
5
|
+
export class BranchTicketPrompt extends BranchRunnable {
|
|
6
|
+
async run(): Promise<void> {
|
|
7
|
+
if (!this.#is_enabled) return;
|
|
8
|
+
|
|
9
|
+
const ticket = await p.text({
|
|
10
|
+
message: this.#message,
|
|
11
|
+
placeholder: "",
|
|
12
|
+
validate: (value) => this.#validate(value),
|
|
13
|
+
initialValue: this.branch_state.ticket,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
if (p.isCancel(ticket)) process.exit(0);
|
|
17
|
+
this.#run_post_effects(ticket ?? "");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get #is_enabled(): boolean {
|
|
21
|
+
return this.config.branch_ticket.enable;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get #is_required(): boolean {
|
|
25
|
+
return this.config.branch_ticket.required;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get #message(): string {
|
|
29
|
+
return this.#is_required
|
|
30
|
+
? "Type ticket / issue number"
|
|
31
|
+
: optional_message("Type ticket / issue number");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#validate(value: string | undefined): string | undefined {
|
|
35
|
+
if (this.#is_required && !value) return "Please enter a ticket / issue";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#run_post_effects(prompt_result: string): void {
|
|
39
|
+
this.branch_state.ticket = prompt_result;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { BranchRunnable } from "./branch-runnable";
|
|
3
|
+
|
|
4
|
+
export class BranchTypePrompt extends BranchRunnable {
|
|
5
|
+
async run(): Promise<void> {
|
|
6
|
+
if (!this.#is_enabled) return;
|
|
7
|
+
|
|
8
|
+
const branch_type = await p.select({
|
|
9
|
+
message: this.#message,
|
|
10
|
+
initialValue: this.#initial_value,
|
|
11
|
+
options: this.#options,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
if (p.isCancel(branch_type)) process.exit(0);
|
|
15
|
+
this.#run_post_effects(branch_type);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
get #is_enabled(): boolean {
|
|
19
|
+
return this.config.branch_type.enable;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get #message(): string {
|
|
23
|
+
return "Select a branch type";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get #initial_value(): string {
|
|
27
|
+
return this.branch_state.type || this.config.commit_type.initial_value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get #options(): {
|
|
31
|
+
label?: string | undefined;
|
|
32
|
+
value: string;
|
|
33
|
+
emoji?: string;
|
|
34
|
+
hint?: string;
|
|
35
|
+
trailer?: string;
|
|
36
|
+
}[] {
|
|
37
|
+
return this.config.commit_type.options;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
#run_post_effects(prompt_result: string): void {
|
|
41
|
+
this.branch_state.type = prompt_result;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { get_value_from_cache, set_value_cache } from "../utils";
|
|
3
|
+
import { optional_message } from "../utils/messages";
|
|
4
|
+
import { BranchRunnable } from "./branch-runnable";
|
|
5
|
+
|
|
6
|
+
export class BranchUserPrompt extends BranchRunnable {
|
|
7
|
+
async run(): Promise<void> {
|
|
8
|
+
if (!this.#is_enabled) return;
|
|
9
|
+
|
|
10
|
+
const user_name = await p.text({
|
|
11
|
+
message: this.#message,
|
|
12
|
+
placeholder: "",
|
|
13
|
+
initialValue: this.#initial_value,
|
|
14
|
+
validate: (value) => this.#validate(value),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
if (p.isCancel(user_name)) process.exit(0);
|
|
18
|
+
this.#run_post_effects(user_name ?? "");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get #is_enabled(): boolean {
|
|
22
|
+
return this.config.branch_user.enable;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
get #is_required(): boolean {
|
|
26
|
+
return this.config.branch_user.required;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get #message(): string {
|
|
30
|
+
return this.#is_required
|
|
31
|
+
? "Type your git username"
|
|
32
|
+
: optional_message("Type your git username");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
get #initial_value(): string {
|
|
36
|
+
return (
|
|
37
|
+
this.branch_state.user ||
|
|
38
|
+
get_value_from_cache(this.prompt_cache, "username")
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
#validate(value: string | undefined): string | undefined {
|
|
43
|
+
if (this.#is_required && !value) return "Please enter a username";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#run_post_effects(prompt_result: string): void {
|
|
47
|
+
this.branch_state.user = prompt_result.replace(/\s+/g, "-").toLowerCase();
|
|
48
|
+
set_value_cache(this.prompt_cache, "username", this.branch_state.user);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { optional_message } from "../utils/messages";
|
|
3
|
+
import { BranchRunnable } from "./branch-runnable";
|
|
4
|
+
|
|
5
|
+
export class BranchVersionPrompt extends BranchRunnable {
|
|
6
|
+
async run(): Promise<void> {
|
|
7
|
+
if (!this.#is_enabled) return;
|
|
8
|
+
|
|
9
|
+
const version = await p.text({
|
|
10
|
+
message: this.#message,
|
|
11
|
+
placeholder: "",
|
|
12
|
+
validate: (value) => this.#validate(value),
|
|
13
|
+
initialValue: this.branch_state.version,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
if (p.isCancel(version)) process.exit(0);
|
|
17
|
+
this.#run_post_effects(version ?? "");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get #is_enabled(): boolean {
|
|
21
|
+
return this.config.branch_version.enable;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get #is_required(): boolean {
|
|
25
|
+
return this.config.branch_version.required;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get #message(): string {
|
|
29
|
+
return this.#is_required
|
|
30
|
+
? "Type version number"
|
|
31
|
+
: optional_message("Type version number");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#validate(value: string | undefined): string | undefined {
|
|
35
|
+
if (this.#is_required && !value) return "Please enter a version";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#run_post_effects(prompt_result: string): void {
|
|
39
|
+
this.branch_state.version = prompt_result;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { get_value_from_cache, set_value_cache } from "../utils";
|
|
3
|
+
import { cache_message, optional_message } from "../utils/messages";
|
|
4
|
+
import { Runnable } from "./runnable";
|
|
5
|
+
|
|
6
|
+
export class CommitBodyPrompt extends Runnable {
|
|
7
|
+
async run(): Promise<void> {
|
|
8
|
+
if (!this.#is_enabled) return;
|
|
9
|
+
|
|
10
|
+
const { initial_value, message } = this.#get_initial_value();
|
|
11
|
+
const commit_body = await p.text({
|
|
12
|
+
message,
|
|
13
|
+
initialValue: initial_value,
|
|
14
|
+
placeholder: "",
|
|
15
|
+
validate: (value) => this.#validate(value),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
if (p.isCancel(commit_body)) process.exit(0);
|
|
19
|
+
this.#run_post_effects(commit_body ?? "");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get #is_enabled(): boolean {
|
|
23
|
+
return this.config.commit_body.enable;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#get_initial_value(): { initial_value: string; message: string } {
|
|
27
|
+
const cache_value = get_value_from_cache(this.prompt_cache, "commit_body");
|
|
28
|
+
if (cache_value) {
|
|
29
|
+
return {
|
|
30
|
+
initial_value: cache_value,
|
|
31
|
+
message: cache_message("Commit body"),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
initial_value: "",
|
|
37
|
+
message: optional_message("Write a detailed description of the changes"),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#validate(value: string | undefined): string | undefined {
|
|
42
|
+
if (this.config.commit_body.required && !value) {
|
|
43
|
+
return "Please enter a description";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#split_by_period(value: string): string {
|
|
48
|
+
if (!this.config.commit_body.split_by_period) return value;
|
|
49
|
+
const sentences = value.split(/\.\s+/).map((sentence) => sentence.trim());
|
|
50
|
+
return sentences.join(".\n");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
#run_post_effects(prompt_result: string): void {
|
|
54
|
+
set_value_cache(this.prompt_cache, "commit_body", prompt_result);
|
|
55
|
+
this.commit_state.body = this.#split_by_period(prompt_result);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { StdioOptions, execSync } from "child_process";
|
|
3
|
+
import { flags } from "../args";
|
|
4
|
+
import { Runnable } from "./runnable";
|
|
5
|
+
import { dry_run_message } from "../utils/messages";
|
|
6
|
+
import { build_commit_string } from "../utils/build-commit-string";
|
|
7
|
+
|
|
8
|
+
export class CommitConfirmPrompt extends Runnable {
|
|
9
|
+
async run(): Promise<void> {
|
|
10
|
+
if (this.#confirm_with_editor) {
|
|
11
|
+
execSync(`${this.#commit_command} --edit`, this.#git_command_options);
|
|
12
|
+
process.exit(0);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (this.#print_commit_output) {
|
|
16
|
+
p.note(
|
|
17
|
+
build_commit_string({
|
|
18
|
+
commit_state: this.commit_state,
|
|
19
|
+
config: this.config,
|
|
20
|
+
colorize: true,
|
|
21
|
+
escape_quotes: false,
|
|
22
|
+
include_trailer: true,
|
|
23
|
+
}),
|
|
24
|
+
"Commit Preview",
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const continue_commit = await this.#get_continue_commit();
|
|
29
|
+
if (!continue_commit) {
|
|
30
|
+
p.log.info("Exiting without commit");
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
p.log.info(
|
|
36
|
+
flags.dry_run
|
|
37
|
+
? dry_run_message("Committing changes...")
|
|
38
|
+
: "Committing changes...",
|
|
39
|
+
);
|
|
40
|
+
execSync(
|
|
41
|
+
this.#commit_command,
|
|
42
|
+
flags.dry_run
|
|
43
|
+
? this.#git_command_options_quiet
|
|
44
|
+
: this.#git_command_options,
|
|
45
|
+
);
|
|
46
|
+
} catch (err) {
|
|
47
|
+
p.log.error("Something went wrong when committing: " + err);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
this.#run_post_effects();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get #confirm_with_editor(): boolean {
|
|
55
|
+
return flags.interactive && this.config.confirm_with_editor;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get #print_commit_output(): boolean {
|
|
59
|
+
return this.config.print_commit_output;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get #confirm_commit(): boolean {
|
|
63
|
+
return this.config.confirm_commit;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
get #git_command_options(): { stdio: StdioOptions; shell?: string } {
|
|
67
|
+
return this.config.overrides.shell
|
|
68
|
+
? { shell: this.config.overrides.shell, stdio: "inherit" as StdioOptions }
|
|
69
|
+
: { stdio: "inherit" as StdioOptions };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
get #git_command_options_quiet(): { stdio: StdioOptions; shell?: string } {
|
|
73
|
+
return this.config.overrides.shell
|
|
74
|
+
? { shell: this.config.overrides.shell, stdio: "pipe" as StdioOptions }
|
|
75
|
+
: { stdio: "pipe" as StdioOptions };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
get #trailer_arg(): string {
|
|
79
|
+
return this.commit_state.trailer
|
|
80
|
+
? `--trailer="${this.commit_state.trailer}"`
|
|
81
|
+
: "";
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
get #commit_command(): string {
|
|
85
|
+
return `git ${flags.git_args} commit -m "${build_commit_string({
|
|
86
|
+
commit_state: this.commit_state,
|
|
87
|
+
config: this.config,
|
|
88
|
+
colorize: false,
|
|
89
|
+
escape_quotes: true,
|
|
90
|
+
include_trailer: false,
|
|
91
|
+
})}" ${this.#trailer_arg} ${this.#dry_run_args}`.trim();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
get #dry_run_args(): string {
|
|
95
|
+
return flags.dry_run ? "--dry-run --porcelain --untracked-files=no" : "";
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async #get_continue_commit(): Promise<boolean> {
|
|
99
|
+
if (!flags.interactive) return true;
|
|
100
|
+
if (!this.#confirm_commit) return true;
|
|
101
|
+
|
|
102
|
+
// dry_run_message
|
|
103
|
+
const continue_commit = (await p.confirm({
|
|
104
|
+
message: flags.dry_run
|
|
105
|
+
? dry_run_message("Confirm Commit?")
|
|
106
|
+
: "Confirm Commit?",
|
|
107
|
+
})) as boolean;
|
|
108
|
+
if (p.isCancel(continue_commit)) process.exit(0);
|
|
109
|
+
return continue_commit;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
#run_post_effects(): void {
|
|
113
|
+
p.log.success("Commit Complete");
|
|
114
|
+
|
|
115
|
+
const user_name = this.prompt_cache.get("username");
|
|
116
|
+
this.prompt_cache.clear();
|
|
117
|
+
if (user_name) this.prompt_cache.set("username", user_name);
|
|
118
|
+
}
|
|
119
|
+
}
|