Skip to content

Commit 06f745d

Browse files
committed
feat: update src
1 parent 92cdf37 commit 06f745d

File tree

10 files changed

+226
-53
lines changed

10 files changed

+226
-53
lines changed

src/autofill.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Try saving your files or stage any new (untracked) files.\
1313
`;
1414

1515
/**
16-
* Generate and fill a commit message in the Git extenside sidebar.
16+
* Generate and fill a commit message in the Git extension sidebar.
1717
*
1818
* Steps:
1919
*

src/cli.ts

Lines changed: 0 additions & 43 deletions
This file was deleted.

src/cli/diffIndexGenerate.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env node
2+
/**
3+
* AutoCommitMsg CLI script.
4+
*/
5+
import { execFileSync } from "child_process";
6+
import { generateMsg } from "../prepareCommitMsg";
7+
import { shouldShowHelp } from "./utils";
8+
9+
const HELP_TEXT: string = `Usage: acm [--cached] [--help|-h]
10+
11+
Check Git changes and generate a commit message.
12+
13+
Options:
14+
--cached Use only staged changes (equivalent to git --cached).
15+
If the flag is omitted, then the standard \`git status\` logic is followed:
16+
look for staged changes and use them, otherwise use unstaged changes.
17+
--help, -h Show this help and exit.`;
18+
19+
const DIFF_FLAGS = [
20+
"diff-index",
21+
"--name-status",
22+
"--find-renames",
23+
"--find-copies",
24+
"--no-color",
25+
];
26+
27+
/**
28+
* Run `git diff-index` and return its stdout as a string.
29+
*
30+
* TODO: Use _diffIndex instead after refactoring for flags.
31+
* @param useCached When true, include only staged changes using `--cached`.
32+
*
33+
* @returns output Diff output from git.
34+
*/
35+
function runGitDiff(useCached: boolean): string {
36+
const flags: string[] = [...DIFF_FLAGS];
37+
38+
if (useCached) {
39+
flags.push("--cached");
40+
}
41+
flags.push("HEAD");
42+
43+
const output: string = execFileSync("git", flags, {
44+
encoding: "utf8",
45+
stdio: ["ignore", "pipe", "pipe"],
46+
});
47+
48+
return output.trim();
49+
}
50+
51+
/**
52+
* Generate a commit message from the current repository diff.
53+
*
54+
* @param useCached When true, include only staged changes using `--cached`.
55+
* @returns Generated commit message text.
56+
*/
57+
export function generateCommitMessage(useCached: boolean): string {
58+
const diffOutput: string = runGitDiff(useCached);
59+
if (!diffOutput) {
60+
throw new Error("No file changes found");
61+
}
62+
63+
const lines: string[] = diffOutput.split("\n");
64+
return generateMsg(lines);
65+
}
66+
67+
/**
68+
* Command-line entry-point.
69+
*
70+
* Accepts an optional `--cached` flag to use staged changes only.
71+
* Prints the generated commit message to stdout.
72+
*/
73+
function main(argv: string[]): void {
74+
if (shouldShowHelp(argv)) {
75+
console.log(HELP_TEXT);
76+
return;
77+
}
78+
const useCached: boolean = argv.includes("--cached");
79+
const msg: string = generateCommitMessage(useCached);
80+
console.log(msg);
81+
}
82+
83+
if (require.main === module) {
84+
try {
85+
main(process.argv.slice(2));
86+
} catch (err) {
87+
const message: string = err instanceof Error ? err.message : String(err);
88+
console.error(`Error: ${message}`);
89+
process.exit(1);
90+
}
91+
}

src/cli/diffIndexGenerateCommit.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env node
2+
/**
3+
* Git commit AutoCommitMsg script.
4+
*/
5+
import { execFileSync } from "child_process";
6+
import { generateCommitMessage } from "./diffIndexGenerate";
7+
import { shouldShowHelp } from "./utils";
8+
9+
const HELP_TEXT: string = `Usage: gacm [--cached] [--help|-h]
10+
11+
Check Git changes, generate a commit message, and run Git commit.
12+
13+
Options:
14+
--cached Use only staged changes (equivalent to git --cached).
15+
If the flag is omitted, then the standard \`git status\` logic is followed:
16+
look for staged changes and use them, otherwise use unstaged changes.
17+
--help, -h Show this help and exit.`;
18+
19+
/**
20+
* Command-line entry-point.
21+
*/
22+
function main(argv: string[]): void {
23+
if (shouldShowHelp(argv)) {
24+
console.log(HELP_TEXT);
25+
return;
26+
}
27+
28+
const useCached: boolean = argv.includes("--cached");
29+
const passthrough: string[] = argv.filter(
30+
(arg: string) => arg !== "--cached",
31+
);
32+
33+
const msg: string = generateCommitMessage(useCached);
34+
35+
const commitArgs: string[] = ["commit", "--edit", "-m", msg, ...passthrough];
36+
execFileSync("git", commitArgs, { stdio: "inherit" });
37+
}
38+
39+
if (require.main === module) {
40+
try {
41+
main(process.argv.slice(2));
42+
} catch (err) {
43+
const message: string = err instanceof Error ? err.message : String(err);
44+
console.error(`Error: ${message}`);
45+
process.exit(1);
46+
}
47+
}

src/cli/generate.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#!/usr/bin/env node
2+
/**
3+
* CLI module to generate a commit message using given input.
4+
*
5+
* This script does not interact with VS Code or Git, it only processes text.
6+
* This works as a Git hook. See shell/README.md for hook usage.
7+
*
8+
* It simply receives text as an argument and prints output to `stdout` for use
9+
* in a hook flow. Or to `stderr`, in the case of a message not appropriate for
10+
* a commit message.
11+
*/
12+
import { generateMsg } from "../prepareCommitMsg";
13+
14+
const HELP_TEXT: string = `Usage: auto_commit_msg_generate DIFF_INDEX_OUTPUT
15+
16+
Generate a commit message from given input.
17+
18+
Arguments:
19+
DIFF_INDEX_OUTPUT Text output from 'git diff-index --name-status HEAD'.
20+
21+
Options:
22+
--help, -h Show this help and exit.`;
23+
24+
/**
25+
* Command-line entry-point.
26+
*
27+
* Returns a suitable generated commit message as text.
28+
*/
29+
import { shouldShowHelp } from "./utils";
30+
31+
/**
32+
* Entry-point for the CLI. Handles help flag and input validation.
33+
*/
34+
function main(args: string[]): void {
35+
if (shouldShowHelp(args)) {
36+
console.log(HELP_TEXT);
37+
return;
38+
}
39+
const linesArg = args[0];
40+
41+
if (typeof linesArg === "undefined") {
42+
throw new Error(
43+
"Exactly one argument is required - text output from diff-index command.",
44+
);
45+
}
46+
47+
const lines = linesArg.split("\n");
48+
49+
if (!lines.length) {
50+
throw new Error("No file changes found");
51+
}
52+
53+
const msg = generateMsg(lines);
54+
console.log(msg);
55+
}
56+
57+
const args = process.argv.slice(2);
58+
try {
59+
main(args);
60+
} catch (err) {
61+
const message: string = err instanceof Error ? err.message : String(err);
62+
console.error(message);
63+
process.exit(1);
64+
}

src/cli/utils.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* CLI utilities shared by bin commands.
3+
*/
4+
5+
/**
6+
* Determine whether help should be displayed.
7+
*
8+
* @param argv Command-line arguments passed to the CLI.
9+
*
10+
* @returns boolean True when `--help` or `-h` is present.
11+
*/
12+
export function shouldShowHelp(argv: string[]): boolean {
13+
return argv.includes("--help") || argv.includes("-h");
14+
}

src/git/parseOutput.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const GIT_STATUS_SPLIT = " -> ";
1717
* Parse a line which was produced by the `git status --short` command.
1818
*/
1919
export function parseStatus(line: string): FileChange {
20-
if (line.length <= 4) {
20+
if (line.length < 4) {
2121
throw new Error(
2222
`Input string must be at least 4 characters. Got: '${line}'`,
2323
);
@@ -54,7 +54,7 @@ export function parseStatus(line: string): FileChange {
5454
* than `undefined`).
5555
*/
5656
export function parseDiffIndex(line: string): FileChange {
57-
if (line.length <= 4) {
57+
if (line.length < 4) {
5858
const errorMsg = `Invalid input. Input string must be at least 4 characters. Got: '${line}'`;
5959
console.error(errorMsg);
6060
throw new Error(errorMsg);

src/test/generate/action.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import * as assert from "assert";
55
import { lookupDiffIndexAction, moveOrRenameMsg } from "../../generate/action";
66

7-
describe("Desribe a file using a single path", function () {
7+
describe("Describe a file using a single path", function () {
88
describe("#lookupDiffIndexAction", function () {
99
it("can describe an updated file", function () {
1010
assert.strictEqual(lookupDiffIndexAction("M"), "update");
@@ -32,7 +32,7 @@ describe("Desribe a file using a single path", function () {
3232
});
3333
});
3434

35-
describe("Desribe a file using two paths", function () {
35+
describe("Describe a file using two paths", function () {
3636
describe("#moveOrRenameFile", function () {
3737
it("can describe a renamed file", function () {
3838
assert.strictEqual(
@@ -73,7 +73,7 @@ describe("Desribe a file using two paths", function () {
7373
);
7474
});
7575

76-
it("can describe a remamed and moved file", function () {
76+
it("can describe a renamed and moved file", function () {
7777
assert.strictEqual(
7878
moveOrRenameMsg("foo.txt", "fizz/bar.txt"),
7979
"move and rename foo.txt to fizz/bar.txt",

src/test/generate/count.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
*/
44
import * as assert from "assert";
55
import {
6-
countFilesDesc,
76
_countByAction,
87
_formatAll,
98
_formatOne,
109
_moveOrRenameFromChange,
10+
countFilesDesc,
1111
} from "../../generate/count";
1212
import { FileChange } from "../../git/parseOutput.d";
1313

@@ -257,7 +257,7 @@ describe("Aggregate counts of files as numeric data", function () {
257257
});
258258
});
259259

260-
describe("give correct actionsand counts for files with different actions", function () {
260+
describe("give correct actions and counts for files with different actions", function () {
261261
it("should handle one created and one updated file", function () {
262262
const changes: FileChange[] = [
263263
{
@@ -457,7 +457,7 @@ describe("Convert action and counts to a readable commit message", function () {
457457
});
458458
});
459459

460-
describe("multiples files", function () {
460+
describe("multiple files", function () {
461461
it("should handle one created file and one updated file", function () {
462462
const actionCounts = {
463463
create: { fileCount: 1 },

src/test/lib/paths.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ describe("Path handling", function () {
119119
assert.strictEqual(result, "foo and bar");
120120
});
121121

122-
it('returns three items joined with commands and an an "and"', function () {
122+
it('returns three items joined with commas and an "and"', function () {
123123
const result = _join(["foo", "bar", "bazz"]);
124124
assert.strictEqual(result, "foo, bar and bazz");
125125
});

0 commit comments

Comments
 (0)