-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommit-msg-hook.ts
More file actions
98 lines (88 loc) · 2.76 KB
/
Copy pathcommit-msg-hook.ts
File metadata and controls
98 lines (88 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/env node
import escapeStringRegexp from "escape-string-regexp";
import { readFileSync, writeFileSync } from "fs";
import { exit } from "process";
import { getConfig } from "./config";
import { GitError, activeBranchName } from "./git-interop";
enum RegExpFlag {
IGNORE_CASE = "i",
}
/**
* Prevent commit subjects that are already in the proper format
* from being formatted again which would duplicate any matched
* branch details and non formatting token characters in the final commit subject.
*
* This allows amending a commit message to work as expected.
*
* @param currentCommitSubject
* @param commitMsgFormat
* @param branchMatches
* @returns The current commit subject removed of any formatting that may have already been applied.
*/
function dedupeCurrentCommitSubject(
currentCommitSubject: string,
commitMsgFormat: string,
branchMatches: RegExpMatchArray,
): string {
const appliedFormatting = branchMatches.reduce(
(msg, branchDetail, index) =>
msg
.replace(`%b${index} | upper`, branchDetail.toUpperCase())
.replace(`%b${index} | lower`, branchDetail.toLowerCase())
.replace(`%b${index}`, branchDetail),
commitMsgFormat
.replace("%m | upper", "")
.replace("%m | lower", "")
.replace("%m", ""),
);
return currentCommitSubject.replace(
new RegExp(escapeStringRegexp(appliedFormatting), RegExpFlag.IGNORE_CASE),
"",
);
}
let branchName: string;
const commitMsgFilePath = process.argv[process.argv.length - 1];
const commitMsgFileLines = readFileSync(commitMsgFilePath)
.toString()
.split(/\r?\n/);
const currentCommitSubject = commitMsgFileLines[0];
const hookConfig = getConfig();
if (hookConfig === undefined) {
exit(0);
}
try {
branchName = activeBranchName();
} catch (error) {
if (!(error instanceof GitError)) {
throw error;
}
exit(0);
}
const branchMatches = branchName.match(
new RegExp(
hookConfig.extractPattern,
hookConfig.extractPatternMatchCase ? undefined : RegExpFlag.IGNORE_CASE,
),
);
if (!branchMatches) {
exit(0);
}
const currentCommitSubjectDeduped = dedupeCurrentCommitSubject(
currentCommitSubject,
hookConfig.commitMsgFormat,
branchMatches,
);
const newCommitSubject = branchMatches
.reduce(
(msg, branchDetail, index) =>
msg
.replace(`%b${index} | upper`, branchDetail.toUpperCase())
.replace(`%b${index} | lower`, branchDetail.toLowerCase())
.replace(`%b${index}`, branchDetail),
hookConfig.commitMsgFormat,
)
.replace("%m | upper", currentCommitSubjectDeduped.toUpperCase())
.replace("%m | lower", currentCommitSubjectDeduped.toLowerCase())
.replace("%m", currentCommitSubjectDeduped);
commitMsgFileLines[0] = newCommitSubject;
writeFileSync(commitMsgFilePath, commitMsgFileLines.join("\n"));