better-commits 1.23.2 → 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.test.ts +0 -64
- package/src/git.ts +0 -72
- 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.test.ts +0 -89
- package/src/prompts/branch-confirm.prompt.ts +0 -149
- 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 -51
- package/src/prompts/commit-confirm.prompt.ts +0 -123
- 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 -66
- 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 -273
- package/src/utils/build-commit-string.ts +0 -163
- 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
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
export const DEFAULT_CONFIG_TEMPLATE = `{
|
|
2
|
-
// Run interactive \`git status\` before composing a commit
|
|
3
|
-
"check_status": true,
|
|
4
|
-
"check_status_autocomplete": true,
|
|
5
|
-
|
|
6
|
-
/* COMMIT FIELDS */
|
|
7
|
-
"commit_type": {
|
|
8
|
-
"enable": true,
|
|
9
|
-
|
|
10
|
-
// Default selected type from options
|
|
11
|
-
"initial_value": "feat",
|
|
12
|
-
|
|
13
|
-
"max_items": 20,
|
|
14
|
-
|
|
15
|
-
// Infer type from the current branch name: user/TYPE/my-branch
|
|
16
|
-
"infer_type_from_branch": true,
|
|
17
|
-
|
|
18
|
-
// Include emoji in prompt label
|
|
19
|
-
"append_emoji_to_label": false,
|
|
20
|
-
|
|
21
|
-
// Include emoji from prompt label in commit message
|
|
22
|
-
"append_emoji_to_commit": false,
|
|
23
|
-
|
|
24
|
-
// "Start" | "After-Colon"
|
|
25
|
-
"emoji_commit_position": "Start",
|
|
26
|
-
|
|
27
|
-
"autocomplete": true,
|
|
28
|
-
|
|
29
|
-
"options": [
|
|
30
|
-
{
|
|
31
|
-
"value": "feat",
|
|
32
|
-
"label": "feat",
|
|
33
|
-
"hint": "A new feature",
|
|
34
|
-
"emoji": "🌟",
|
|
35
|
-
"trailer": "Changelog: feature"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
"value": "fix",
|
|
39
|
-
"label": "fix",
|
|
40
|
-
"hint": "A bug fix",
|
|
41
|
-
"emoji": "🐛",
|
|
42
|
-
"trailer": "Changelog: fix"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"value": "docs",
|
|
46
|
-
"label": "docs",
|
|
47
|
-
"hint": "Documentation only changes",
|
|
48
|
-
"emoji": "📚",
|
|
49
|
-
"trailer": "Changelog: documentation"
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
"value": "refactor",
|
|
53
|
-
"label": "refactor",
|
|
54
|
-
"hint": "A code change that neither fixes a bug nor adds a feature",
|
|
55
|
-
"emoji": "🔨",
|
|
56
|
-
"trailer": "Changelog: refactor"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"value": "perf",
|
|
60
|
-
"label": "perf",
|
|
61
|
-
"hint": "A code change that improves performance",
|
|
62
|
-
"emoji": "🚀",
|
|
63
|
-
"trailer": "Changelog: performance"
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
"value": "test",
|
|
67
|
-
"label": "test",
|
|
68
|
-
"hint": "Adding missing tests or correcting existing tests",
|
|
69
|
-
"emoji": "🚨",
|
|
70
|
-
"trailer": "Changelog: test"
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
"value": "build",
|
|
74
|
-
"label": "build",
|
|
75
|
-
"hint": "Changes that affect the build system or external dependencies",
|
|
76
|
-
"emoji": "🚧",
|
|
77
|
-
"trailer": "Changelog: build"
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
"value": "ci",
|
|
81
|
-
"label": "ci",
|
|
82
|
-
"hint": "Changes to our CI configuration files and scripts",
|
|
83
|
-
"emoji": "🤖",
|
|
84
|
-
"trailer": "Changelog: ci"
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
"value": "chore",
|
|
88
|
-
"label": "chore",
|
|
89
|
-
"hint": "Other changes that do not modify src or test files",
|
|
90
|
-
"emoji": "🧹",
|
|
91
|
-
"trailer": "Changelog: chore"
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
"value": "",
|
|
95
|
-
"label": "none"
|
|
96
|
-
}
|
|
97
|
-
]
|
|
98
|
-
},
|
|
99
|
-
|
|
100
|
-
"commit_scope": {
|
|
101
|
-
"enable": true,
|
|
102
|
-
|
|
103
|
-
// If true, users can type a scope not listed in options
|
|
104
|
-
"custom_scope": false,
|
|
105
|
-
|
|
106
|
-
// Default selected scope from options
|
|
107
|
-
"initial_value": "app",
|
|
108
|
-
|
|
109
|
-
// Infer scope from the current branch name: user/type/ticket-SCOPE-my-branch
|
|
110
|
-
"infer_scope_from_branch": true,
|
|
111
|
-
|
|
112
|
-
"max_items": 20,
|
|
113
|
-
"autocomplete": true,
|
|
114
|
-
"options": [
|
|
115
|
-
{ "value": "app", "label": "app" },
|
|
116
|
-
{ "value": "shared", "label": "shared" },
|
|
117
|
-
{ "value": "server", "label": "server" },
|
|
118
|
-
{ "value": "tools", "label": "tools" },
|
|
119
|
-
{ "value": "", "label": "none" }
|
|
120
|
-
]
|
|
121
|
-
},
|
|
122
|
-
|
|
123
|
-
"check_ticket": {
|
|
124
|
-
// Infer ticket / issue from the branch name - user/type/TICKET-my-branch
|
|
125
|
-
"infer_ticket": true,
|
|
126
|
-
|
|
127
|
-
// Prompt for confirmation / edit before using an inferred ticket
|
|
128
|
-
"confirm_ticket": true,
|
|
129
|
-
|
|
130
|
-
// Add the ticket to the commit title - feat(app): TICKET my commit title
|
|
131
|
-
"add_to_title": true,
|
|
132
|
-
|
|
133
|
-
// Deprecated, prefer \`prepend_hashtag\`
|
|
134
|
-
"append_hashtag": false,
|
|
135
|
-
|
|
136
|
-
// "Never" | "Prompt" | "Always" - 12345 --> #12345
|
|
137
|
-
"prepend_hashtag": "Never",
|
|
138
|
-
|
|
139
|
-
// Wrap the ticket in the commit title: "" | "[]" | "()" | "{}"
|
|
140
|
-
"surround": "",
|
|
141
|
-
|
|
142
|
-
// "start" | "end" | "before-colon" | "beginning"
|
|
143
|
-
"title_position": "start"
|
|
144
|
-
},
|
|
145
|
-
|
|
146
|
-
"commit_title": {
|
|
147
|
-
// Includes total size of title + type + scope + ticket
|
|
148
|
-
"max_size": 70
|
|
149
|
-
},
|
|
150
|
-
|
|
151
|
-
"commit_body": {
|
|
152
|
-
"enable": true,
|
|
153
|
-
"required": false,
|
|
154
|
-
|
|
155
|
-
// Split sentences into multiple lines automatically
|
|
156
|
-
"split_by_period": false
|
|
157
|
-
},
|
|
158
|
-
|
|
159
|
-
"commit_footer": {
|
|
160
|
-
"enable": true,
|
|
161
|
-
"initial_value": [],
|
|
162
|
-
|
|
163
|
-
// "closes", "trailer", "breaking-change", "deprecated", "custom"
|
|
164
|
-
"options": ["closes", "trailer", "breaking-change", "deprecated", "custom"]
|
|
165
|
-
},
|
|
166
|
-
|
|
167
|
-
"breaking_change": {
|
|
168
|
-
// Adds \`!\` to the commit title when a breaking change is selected
|
|
169
|
-
"add_exclamation_to_title": true
|
|
170
|
-
},
|
|
171
|
-
|
|
172
|
-
// Confirm / edit with $GIT_EDITOR or $EDITOR
|
|
173
|
-
"confirm_with_editor": false,
|
|
174
|
-
|
|
175
|
-
// Show a final confirmation prompt before running git commit
|
|
176
|
-
"confirm_commit": true,
|
|
177
|
-
|
|
178
|
-
// Reuse the last known value from a previous canceled or failed commit
|
|
179
|
-
"cache_last_value": true,
|
|
180
|
-
|
|
181
|
-
// Pretty-print the final commit preview before execution
|
|
182
|
-
"print_commit_output": true,
|
|
183
|
-
|
|
184
|
-
/* BRANCH FIELDS */
|
|
185
|
-
// Optional shell commands to run before / after creating branches or worktrees
|
|
186
|
-
"branch_pre_commands": [],
|
|
187
|
-
"branch_post_commands": [],
|
|
188
|
-
"worktree_pre_commands": [],
|
|
189
|
-
"worktree_post_commands": [],
|
|
190
|
-
|
|
191
|
-
"branch_user": {
|
|
192
|
-
"enable": true,
|
|
193
|
-
"required": false,
|
|
194
|
-
|
|
195
|
-
// "/" | "-" | "_" - user/feat/my-branch
|
|
196
|
-
"separator": "/"
|
|
197
|
-
},
|
|
198
|
-
|
|
199
|
-
"branch_type": {
|
|
200
|
-
"enable": true,
|
|
201
|
-
"separator": "/",
|
|
202
|
-
"autocomplete": true,
|
|
203
|
-
},
|
|
204
|
-
|
|
205
|
-
"branch_scope": {
|
|
206
|
-
"enable": true,
|
|
207
|
-
"separator": "-",
|
|
208
|
-
"autocomplete": true,
|
|
209
|
-
},
|
|
210
|
-
|
|
211
|
-
"branch_ticket": {
|
|
212
|
-
"enable": true,
|
|
213
|
-
"required": false,
|
|
214
|
-
"separator": "-"
|
|
215
|
-
},
|
|
216
|
-
|
|
217
|
-
"branch_version": {
|
|
218
|
-
"enable": false,
|
|
219
|
-
"required": false,
|
|
220
|
-
"separator": "/"
|
|
221
|
-
},
|
|
222
|
-
|
|
223
|
-
"branch_description": {
|
|
224
|
-
// Maximum length for the description segment of the branch name
|
|
225
|
-
"max_length": 70,
|
|
226
|
-
|
|
227
|
-
// Allowed values: "" | "/" | "-" | "_"
|
|
228
|
-
"separator": ""
|
|
229
|
-
},
|
|
230
|
-
|
|
231
|
-
// "branch" | "worktree"
|
|
232
|
-
"branch_action_default": "branch",
|
|
233
|
-
|
|
234
|
-
// Order of values in the final branch name
|
|
235
|
-
"branch_order": ["user", "version", "type", "ticket", "scope", "description"],
|
|
236
|
-
|
|
237
|
-
// Deprecated, prefer \`worktrees.enable\`
|
|
238
|
-
"enable_worktrees": true,
|
|
239
|
-
|
|
240
|
-
"worktrees": {
|
|
241
|
-
// If false, always create a branch instead of prompting for a worktree
|
|
242
|
-
"enable": true,
|
|
243
|
-
|
|
244
|
-
// Directory where worktrees are created
|
|
245
|
-
"base_path": "..",
|
|
246
|
-
|
|
247
|
-
// Available template variables include:
|
|
248
|
-
// {{repo_name}}, {{branch_description}}, {{user}}, {{type}}, {{scope}}, {{ticket}}, {{version}}
|
|
249
|
-
"folder_template": "{{repo_name}}-{{ticket}}-{{branch_description}}"
|
|
250
|
-
},
|
|
251
|
-
|
|
252
|
-
/* OTHER FIELDS */
|
|
253
|
-
"overrides": {
|
|
254
|
-
// Useful on Windows or for shells with different multiline behavior
|
|
255
|
-
"shell": "/bin/sh"
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
`;
|
package/src/git.test.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
const mocked = vi.hoisted(() => ({
|
|
4
|
-
error: vi.fn(),
|
|
5
|
-
execSync: vi.fn(),
|
|
6
|
-
}));
|
|
7
|
-
|
|
8
|
-
vi.mock("child_process", () => ({
|
|
9
|
-
execSync: mocked.execSync,
|
|
10
|
-
}));
|
|
11
|
-
|
|
12
|
-
vi.mock("@clack/prompts", () => ({
|
|
13
|
-
log: {
|
|
14
|
-
error: mocked.error,
|
|
15
|
-
},
|
|
16
|
-
}));
|
|
17
|
-
|
|
18
|
-
vi.mock("picocolors", () => ({
|
|
19
|
-
default: {
|
|
20
|
-
red: (value: string) => value,
|
|
21
|
-
},
|
|
22
|
-
}));
|
|
23
|
-
|
|
24
|
-
vi.mock("./args", () => ({
|
|
25
|
-
flags: {
|
|
26
|
-
git_args: "",
|
|
27
|
-
},
|
|
28
|
-
}));
|
|
29
|
-
|
|
30
|
-
describe("ensure_staged_changes", () => {
|
|
31
|
-
beforeEach(() => {
|
|
32
|
-
mocked.error.mockReset();
|
|
33
|
-
mocked.execSync.mockReset();
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it("does not exit when staged changes exist", async () => {
|
|
37
|
-
const { ensure_staged_changes } = await import("./git");
|
|
38
|
-
const exit = vi.spyOn(process, "exit").mockImplementation(() => {
|
|
39
|
-
throw new Error("process.exit");
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
mocked.execSync.mockReturnValue(Buffer.from("A src/git.ts\n"));
|
|
43
|
-
|
|
44
|
-
ensure_staged_changes();
|
|
45
|
-
|
|
46
|
-
expect(exit).not.toHaveBeenCalled();
|
|
47
|
-
expect(mocked.error).not.toHaveBeenCalled();
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("exits early when no staged changes exist", async () => {
|
|
51
|
-
const { ensure_staged_changes } = await import("./git");
|
|
52
|
-
const exit = vi.spyOn(process, "exit").mockImplementation(() => {
|
|
53
|
-
throw new Error("process.exit");
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
mocked.execSync.mockReturnValue(Buffer.from(" M src/git.ts\n"));
|
|
57
|
-
|
|
58
|
-
expect(() => ensure_staged_changes()).toThrow("process.exit");
|
|
59
|
-
expect(mocked.error).toHaveBeenCalledWith(
|
|
60
|
-
'no changes added to commit (use "git add" and/or "git commit -a")',
|
|
61
|
-
);
|
|
62
|
-
expect(exit).toHaveBeenCalledWith(0);
|
|
63
|
-
});
|
|
64
|
-
});
|
package/src/git.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
#! /usr/bin/env node
|
|
2
|
-
import { execSync } from "child_process";
|
|
3
|
-
import * as p from "@clack/prompts";
|
|
4
|
-
import color from "picocolors";
|
|
5
|
-
import { flags } from "./args";
|
|
6
|
-
|
|
7
|
-
const porcelain_states = ["M", "T", "R", "D", "A", "C"];
|
|
8
|
-
|
|
9
|
-
export function git_status(): { index: string[]; work_tree: string[] } {
|
|
10
|
-
let status = "";
|
|
11
|
-
try {
|
|
12
|
-
status = execSync(`git ${flags.git_args} status --porcelain`, {
|
|
13
|
-
stdio: "pipe",
|
|
14
|
-
}).toString();
|
|
15
|
-
} catch (err) {
|
|
16
|
-
p.log.error(color.red("Failed to git status" + err));
|
|
17
|
-
return { index: [], work_tree: [] };
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const lines = status.split("\n");
|
|
21
|
-
const work_tree: string[] = [];
|
|
22
|
-
const index: string[] = [];
|
|
23
|
-
lines.forEach((v) => {
|
|
24
|
-
const line = v.trimEnd();
|
|
25
|
-
if (!line) return;
|
|
26
|
-
|
|
27
|
-
const path_plus_file = line.substring(2).trim();
|
|
28
|
-
const first_char = line.charAt(0).trim();
|
|
29
|
-
const second_char = line.charAt(1).trim();
|
|
30
|
-
|
|
31
|
-
// Untracked, always dirty
|
|
32
|
-
if (first_char === "?" || second_char === "?") {
|
|
33
|
-
work_tree.push(path_plus_file);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (porcelain_states.includes(first_char)) {
|
|
37
|
-
index.push(path_plus_file);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (porcelain_states.includes(second_char)) {
|
|
41
|
-
work_tree.push(path_plus_file);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
return { index, work_tree };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function git_add(files: string[]) {
|
|
49
|
-
const space_delimited_files = files.join(" ");
|
|
50
|
-
if (space_delimited_files) {
|
|
51
|
-
try {
|
|
52
|
-
execSync(`git ${flags.git_args} add ${space_delimited_files}`, {
|
|
53
|
-
stdio: "pipe",
|
|
54
|
-
}).toString();
|
|
55
|
-
p.log.success(color.green("Changes successfully staged"));
|
|
56
|
-
} catch (err) {
|
|
57
|
-
p.log.error(color.red("Failed to stage changes"));
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function ensure_staged_changes(): void {
|
|
63
|
-
const updated_status = git_status();
|
|
64
|
-
if (updated_status.index.length) return;
|
|
65
|
-
|
|
66
|
-
p.log.error(
|
|
67
|
-
color.red(
|
|
68
|
-
'no changes added to commit (use "git add" and/or "git commit -a")',
|
|
69
|
-
),
|
|
70
|
-
);
|
|
71
|
-
process.exit(0);
|
|
72
|
-
}
|
package/src/help.ts
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { execSync } from "child_process";
|
|
2
|
-
import { InferOutput } from "valibot";
|
|
3
|
-
import { flags } from "./args";
|
|
4
|
-
import { get_package_version } from "./utils";
|
|
5
|
-
import {
|
|
6
|
-
infer_scope_from_git,
|
|
7
|
-
infer_ticket_from_git,
|
|
8
|
-
infer_type_from_git,
|
|
9
|
-
} from "./utils/infer";
|
|
10
|
-
import { Config } from "./valibot-state";
|
|
11
|
-
import color from "picocolors";
|
|
12
|
-
|
|
13
|
-
const ADDITIONAL_COMMAND_DEFINITIONS: Record<string, string> = {
|
|
14
|
-
"better-branch": "Create a branch or worktree from a guided prompt flow.",
|
|
15
|
-
"better-commits-init":
|
|
16
|
-
"Create a .better-commits.jsonc config in this repository.",
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const CLI_FLAG_DEFINITIONS: Record<string, string> = {
|
|
20
|
-
"--no-interactive": "Run without tui prompts.",
|
|
21
|
-
"--dry-run": "Print the commit command without creating a commit.",
|
|
22
|
-
"--help": "Show help information and exit.",
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const COMMIT_FLAG_DEFINITIONS: Record<string, string> = {
|
|
26
|
-
"--type": "Set commit type (can be inferred from branch).",
|
|
27
|
-
"--scope": "Set commit scope (can be inferred from branch).",
|
|
28
|
-
"--title": "Set commit title/description.",
|
|
29
|
-
"--body": "Set commit body text.",
|
|
30
|
-
"--ticket": "Set ticket / issue (can be inferred from branch).",
|
|
31
|
-
"--closes": "Set closes footer (true/false).",
|
|
32
|
-
"--trailer": "Set trailer footer value.",
|
|
33
|
-
"--breaking-title": "Set breaking-change title footer.",
|
|
34
|
-
"--breaking-body": "Set breaking-change body footer.",
|
|
35
|
-
"--deprecates-title": "Set deprecates footer title text.",
|
|
36
|
-
"--deprecates-body": "Set deprecates footer body text.",
|
|
37
|
-
"--custom-footer": "Set a custom footer line.",
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const GIT_FLAG_DEFINITIONS: Record<string, string> = {
|
|
41
|
-
"--git-dir": "Set the path to the .git directory.",
|
|
42
|
-
"--work-tree": "Set the path to the working tree root.",
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
function to_definition_lines(definitions: Record<string, string>): string {
|
|
46
|
-
const description_column = 26;
|
|
47
|
-
const minimum_spacing = 2;
|
|
48
|
-
const indent = " ";
|
|
49
|
-
|
|
50
|
-
return Object.entries(definitions)
|
|
51
|
-
.map(([name, description]) => {
|
|
52
|
-
const spaces = Math.max(
|
|
53
|
-
minimum_spacing,
|
|
54
|
-
description_column - name.length,
|
|
55
|
-
);
|
|
56
|
-
return `${indent}${name}${" ".repeat(spaces)}${description}`;
|
|
57
|
-
})
|
|
58
|
-
.join("\n");
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export function print_help_text(
|
|
62
|
-
config: InferOutput<typeof Config>,
|
|
63
|
-
config_source: "repository" | "global" | "none",
|
|
64
|
-
) {
|
|
65
|
-
const version = get_package_version();
|
|
66
|
-
|
|
67
|
-
let branch = "(none)";
|
|
68
|
-
try {
|
|
69
|
-
branch =
|
|
70
|
-
execSync(`git ${flags.git_args} branch --show-current`, { stdio: "pipe" })
|
|
71
|
-
.toString()
|
|
72
|
-
.trim() || "(none)";
|
|
73
|
-
} catch {
|
|
74
|
-
// noop
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const inferred_type =
|
|
78
|
-
infer_type_from_git(config.commit_type.options, flags.git_args) ||
|
|
79
|
-
"Unknown";
|
|
80
|
-
const inferred_ticket = config.check_ticket.infer_ticket
|
|
81
|
-
? infer_ticket_from_git(
|
|
82
|
-
{
|
|
83
|
-
append_hashtag: config.check_ticket.append_hashtag,
|
|
84
|
-
prepend_hashtag: config.check_ticket.prepend_hashtag,
|
|
85
|
-
},
|
|
86
|
-
flags.git_args,
|
|
87
|
-
) || "Unknown"
|
|
88
|
-
: "Infer Disabled";
|
|
89
|
-
const inferred_scope = config.commit_scope.infer_scope_from_branch
|
|
90
|
-
? infer_scope_from_git(config.commit_scope.options, flags.git_args) ||
|
|
91
|
-
"Unknown"
|
|
92
|
-
: "Infer Disabled";
|
|
93
|
-
|
|
94
|
-
const types = config.commit_type.options
|
|
95
|
-
.map((option) => option.value)
|
|
96
|
-
.join(", ")
|
|
97
|
-
.trim();
|
|
98
|
-
const scopes = config.commit_scope.options
|
|
99
|
-
.map((option) => option.value)
|
|
100
|
-
.join(", ")
|
|
101
|
-
.trim();
|
|
102
|
-
const cli_flags = to_definition_lines(CLI_FLAG_DEFINITIONS);
|
|
103
|
-
const git_flags = to_definition_lines(GIT_FLAG_DEFINITIONS);
|
|
104
|
-
const commit_flags = to_definition_lines(COMMIT_FLAG_DEFINITIONS);
|
|
105
|
-
const additional_commands = to_definition_lines(
|
|
106
|
-
ADDITIONAL_COMMAND_DEFINITIONS,
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
console.log(`
|
|
110
|
-
${color.green(" better-commits")} ${color.gray("v" + version)}
|
|
111
|
-
|
|
112
|
-
${color.gray("BRANCH")}
|
|
113
|
-
${branch}
|
|
114
|
-
${color.gray("Type")} ${color.blue(inferred_type)} ${color.gray("·")} ${color.gray("Scope")} ${color.cyan(inferred_scope)} ${color.gray("·")} ${color.gray("Ticket")} ${color.magenta(inferred_ticket)}
|
|
115
|
-
|
|
116
|
-
${color.gray("CONFIGURATION")}
|
|
117
|
-
${config_source}
|
|
118
|
-
|
|
119
|
-
${color.gray("Types")}
|
|
120
|
-
${types}
|
|
121
|
-
|
|
122
|
-
${color.gray("Scopes")}
|
|
123
|
-
${scopes}
|
|
124
|
-
|
|
125
|
-
${color.gray("CLI FLAGS")}
|
|
126
|
-
${cli_flags}
|
|
127
|
-
|
|
128
|
-
${color.gray("Commit Flags")}
|
|
129
|
-
${commit_flags}
|
|
130
|
-
|
|
131
|
-
${color.gray("Git Flags (Advanced)")}
|
|
132
|
-
${git_flags}
|
|
133
|
-
|
|
134
|
-
${color.gray("ADDITIONAL COMMANDS")}
|
|
135
|
-
${additional_commands}
|
|
136
|
-
|
|
137
|
-
`);
|
|
138
|
-
}
|
package/src/index.test.ts
DELETED
package/src/index.ts
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
#! /usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { chdir } from "process";
|
|
4
|
-
import * as p from "@clack/prompts";
|
|
5
|
-
import { InferInput, InferOutput, ValiError, parse } from "valibot";
|
|
6
|
-
import { CommitState, Config } from "./valibot-state";
|
|
7
|
-
import {
|
|
8
|
-
load_setup,
|
|
9
|
-
get_git_root,
|
|
10
|
-
NOOP_PROMPT_CACHE,
|
|
11
|
-
ConfigSource,
|
|
12
|
-
} from "./utils";
|
|
13
|
-
import { create_strict_commit_state } from "./utils/no-interactive-validation";
|
|
14
|
-
import Configstore from "configstore";
|
|
15
|
-
import { CommitTypePrompt } from "./prompts/commit-type.prompt";
|
|
16
|
-
import { Runnable } from "./prompts/runnable";
|
|
17
|
-
import { CommitScopePrompt } from "./prompts/commit-scope.prompt";
|
|
18
|
-
import { CommitTicketPrompt } from "./prompts/commit-ticket.prompt";
|
|
19
|
-
import { CommitTitlePrompt } from "./prompts/commit-title.prompt";
|
|
20
|
-
import { CommitBodyPrompt } from "./prompts/commit-body.prompt";
|
|
21
|
-
import { CommitFooterPrompt } from "./prompts/commit-footer.prompt";
|
|
22
|
-
import { CommitConfirmPrompt } from "./prompts/commit-confirm.prompt";
|
|
23
|
-
import { CommitStatusPrompt } from "./prompts/commit-status.prompt";
|
|
24
|
-
import { flags } from "./args";
|
|
25
|
-
import { get_package_version } from "./utils";
|
|
26
|
-
import { infer_not_interactive } from "./utils/infer";
|
|
27
|
-
import { print_help_text } from "./help";
|
|
28
|
-
|
|
29
|
-
type PromptCtor = new (
|
|
30
|
-
config: InferOutput<typeof Config>,
|
|
31
|
-
commit_state: InferOutput<typeof CommitState>,
|
|
32
|
-
prompt_cache: Configstore,
|
|
33
|
-
) => Runnable;
|
|
34
|
-
|
|
35
|
-
const promptCtors: PromptCtor[] = [
|
|
36
|
-
CommitStatusPrompt,
|
|
37
|
-
CommitTypePrompt,
|
|
38
|
-
CommitScopePrompt,
|
|
39
|
-
CommitTicketPrompt,
|
|
40
|
-
CommitTitlePrompt,
|
|
41
|
-
CommitBodyPrompt,
|
|
42
|
-
CommitFooterPrompt,
|
|
43
|
-
CommitConfirmPrompt,
|
|
44
|
-
];
|
|
45
|
-
|
|
46
|
-
const { config, config_source } = load_setup();
|
|
47
|
-
|
|
48
|
-
main(config, config_source);
|
|
49
|
-
|
|
50
|
-
export async function main(
|
|
51
|
-
config: InferOutput<typeof Config>,
|
|
52
|
-
config_source: ConfigSource,
|
|
53
|
-
) {
|
|
54
|
-
chdir(get_git_root());
|
|
55
|
-
|
|
56
|
-
if (flags.version) {
|
|
57
|
-
const version = get_package_version();
|
|
58
|
-
p.log.step("Better Commits v" + version);
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (flags.help) {
|
|
63
|
-
print_help_text(config, config_source);
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const infer_state = infer_not_interactive(config);
|
|
68
|
-
const flags_plus_infer: InferInput<typeof CommitState> = {
|
|
69
|
-
...flags.commit_state,
|
|
70
|
-
type: (flags.commit_state.type || infer_state?.type) ?? "",
|
|
71
|
-
scope: (flags.commit_state.scope || infer_state?.scope) ?? "",
|
|
72
|
-
ticket: (flags.commit_state.ticket || infer_state?.ticket) ?? "",
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const commit_state = parse(CommitState, flags_plus_infer);
|
|
76
|
-
|
|
77
|
-
if (!flags.interactive) {
|
|
78
|
-
try {
|
|
79
|
-
parse(create_strict_commit_state(config), commit_state);
|
|
80
|
-
} catch (err) {
|
|
81
|
-
if (err instanceof ValiError) {
|
|
82
|
-
p.log.error(`Invalid commit input: ${err.message}`);
|
|
83
|
-
} else {
|
|
84
|
-
p.log.error(`Failed to validate commit input: ${err}`);
|
|
85
|
-
}
|
|
86
|
-
process.exit(0);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const prompt_cache = config.cache_last_value
|
|
91
|
-
? new Configstore("better-commits")
|
|
92
|
-
: NOOP_PROMPT_CACHE;
|
|
93
|
-
|
|
94
|
-
const prompts_to_run = flags.interactive
|
|
95
|
-
? promptCtors
|
|
96
|
-
: [CommitConfirmPrompt];
|
|
97
|
-
|
|
98
|
-
for (const Prompt of prompts_to_run) {
|
|
99
|
-
await new Prompt(config, commit_state, prompt_cache).run();
|
|
100
|
-
}
|
|
101
|
-
}
|