@ksw8954/git-ai-commit 1.0.5 → 1.0.7
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/commands/ai.d.ts.map +1 -1
- package/dist/commands/ai.js +11 -0
- package/dist/commands/ai.js.map +1 -1
- package/dist/commands/commit.d.ts +2 -1
- package/dist/commands/commit.d.ts.map +1 -1
- package/dist/commands/commit.js +140 -59
- package/dist/commands/commit.js.map +1 -1
- package/dist/commands/git.d.ts +5 -0
- package/dist/commands/git.d.ts.map +1 -1
- package/dist/commands/git.js +48 -0
- package/dist/commands/git.js.map +1 -1
- package/dist/commands/tag.d.ts +3 -0
- package/dist/commands/tag.d.ts.map +1 -1
- package/dist/commands/tag.js +138 -12
- package/dist/commands/tag.js.map +1 -1
- package/dist/prompts/commit.d.ts.map +1 -1
- package/dist/prompts/commit.js +3 -1
- package/dist/prompts/commit.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/ai.test.ts +38 -0
- package/src/__tests__/git.test.ts +101 -1
- package/src/__tests__/preCommit.test.ts +146 -0
- package/src/__tests__/tagCommand.test.ts +182 -1
- package/src/commands/ai.ts +13 -0
- package/src/commands/commit.ts +168 -69
- package/src/commands/git.ts +48 -0
- package/src/commands/tag.ts +159 -12
- package/src/prompts/commit.ts +3 -1
package/dist/commands/tag.js
CHANGED
|
@@ -54,6 +54,63 @@ class TagCommand {
|
|
|
54
54
|
process.exit(1);
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
|
+
// Check if tag already exists locally
|
|
58
|
+
const localTagExists = await git_1.GitService.tagExists(trimmedName);
|
|
59
|
+
let remoteTagExists = false;
|
|
60
|
+
let wasTagReplaced = false;
|
|
61
|
+
if (localTagExists) {
|
|
62
|
+
console.log(`⚠️ Tag ${trimmedName} already exists locally.`);
|
|
63
|
+
const shouldDelete = await this.confirmTagDelete(trimmedName);
|
|
64
|
+
if (!shouldDelete) {
|
|
65
|
+
console.log('Tag creation cancelled by user.');
|
|
66
|
+
await log_1.LogService.append({
|
|
67
|
+
command: 'tag',
|
|
68
|
+
args: { name: trimmedName, ...options, apiKey: options.apiKey ? '***' : undefined },
|
|
69
|
+
status: 'cancelled',
|
|
70
|
+
details: 'user declined to replace existing tag'
|
|
71
|
+
});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// Check if tag exists on remote
|
|
75
|
+
remoteTagExists = await git_1.GitService.remoteTagExists(trimmedName);
|
|
76
|
+
if (remoteTagExists) {
|
|
77
|
+
console.log(`⚠️ Tag ${trimmedName} also exists on remote.`);
|
|
78
|
+
const shouldDeleteRemote = await this.confirmRemoteTagDelete(trimmedName);
|
|
79
|
+
if (shouldDeleteRemote) {
|
|
80
|
+
console.log(`Deleting remote tag ${trimmedName}...`);
|
|
81
|
+
const remoteDeleted = await git_1.GitService.deleteRemoteTag(trimmedName);
|
|
82
|
+
if (!remoteDeleted) {
|
|
83
|
+
console.error('❌ Failed to delete remote tag');
|
|
84
|
+
await log_1.LogService.append({
|
|
85
|
+
command: 'tag',
|
|
86
|
+
args: { name: trimmedName, ...options, apiKey: options.apiKey ? '***' : undefined },
|
|
87
|
+
status: 'failure',
|
|
88
|
+
details: 'remote tag deletion failed'
|
|
89
|
+
});
|
|
90
|
+
process.exit(1);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
console.log(`✅ Remote tag ${trimmedName} deleted`);
|
|
94
|
+
remoteTagExists = false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Delete local tag
|
|
98
|
+
console.log(`Deleting local tag ${trimmedName}...`);
|
|
99
|
+
const localDeleted = await git_1.GitService.deleteLocalTag(trimmedName);
|
|
100
|
+
if (!localDeleted) {
|
|
101
|
+
console.error('❌ Failed to delete local tag');
|
|
102
|
+
await log_1.LogService.append({
|
|
103
|
+
command: 'tag',
|
|
104
|
+
args: { name: trimmedName, ...options, apiKey: options.apiKey ? '***' : undefined },
|
|
105
|
+
status: 'failure',
|
|
106
|
+
details: 'local tag deletion failed'
|
|
107
|
+
});
|
|
108
|
+
process.exit(1);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
console.log(`✅ Local tag ${trimmedName} deleted`);
|
|
112
|
+
wasTagReplaced = true;
|
|
113
|
+
}
|
|
57
114
|
let tagMessage = options.message?.trim();
|
|
58
115
|
if (!tagMessage) {
|
|
59
116
|
console.log('Collecting commit history for tag notes...');
|
|
@@ -141,20 +198,53 @@ class TagCommand {
|
|
|
141
198
|
console.log(`✅ Tag ${trimmedName} created successfully!`);
|
|
142
199
|
const shouldPush = await this.confirmTagPush(trimmedName);
|
|
143
200
|
if (shouldPush) {
|
|
144
|
-
|
|
145
|
-
const
|
|
146
|
-
if (
|
|
147
|
-
console.log(
|
|
201
|
+
// If tag was replaced or remote tag still exists, use force push
|
|
202
|
+
const needsForcePush = wasTagReplaced || remoteTagExists;
|
|
203
|
+
if (needsForcePush) {
|
|
204
|
+
console.log(`⚠️ Tag ${trimmedName} exists on remote. Force push is required.`);
|
|
205
|
+
const shouldForcePush = await this.confirmForcePush(trimmedName);
|
|
206
|
+
if (!shouldForcePush) {
|
|
207
|
+
console.log('Tag push cancelled by user.');
|
|
208
|
+
await log_1.LogService.append({
|
|
209
|
+
command: 'tag',
|
|
210
|
+
args: { name: trimmedName, ...options, apiKey: options.apiKey ? '***' : undefined },
|
|
211
|
+
status: 'cancelled',
|
|
212
|
+
details: 'user declined force push'
|
|
213
|
+
});
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
console.log(`Force pushing tag ${trimmedName} to remote...`);
|
|
217
|
+
const pushSuccess = await git_1.GitService.forcePushTag(trimmedName);
|
|
218
|
+
if (pushSuccess) {
|
|
219
|
+
console.log(`✅ Tag ${trimmedName} force pushed successfully!`);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
console.error('❌ Failed to force push tag to remote');
|
|
223
|
+
await log_1.LogService.append({
|
|
224
|
+
command: 'tag',
|
|
225
|
+
args: { name: trimmedName, ...options, apiKey: options.apiKey ? '***' : undefined },
|
|
226
|
+
status: 'failure',
|
|
227
|
+
details: 'tag force push failed'
|
|
228
|
+
});
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
148
231
|
}
|
|
149
232
|
else {
|
|
150
|
-
console.
|
|
151
|
-
await
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
233
|
+
console.log(`Pushing tag ${trimmedName} to remote...`);
|
|
234
|
+
const pushSuccess = await git_1.GitService.pushTag(trimmedName);
|
|
235
|
+
if (pushSuccess) {
|
|
236
|
+
console.log(`✅ Tag ${trimmedName} pushed successfully!`);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
console.error('❌ Failed to push tag to remote');
|
|
240
|
+
await log_1.LogService.append({
|
|
241
|
+
command: 'tag',
|
|
242
|
+
args: { name: trimmedName, ...options, apiKey: options.apiKey ? '***' : undefined },
|
|
243
|
+
status: 'failure',
|
|
244
|
+
details: 'tag push failed'
|
|
245
|
+
});
|
|
246
|
+
process.exit(1);
|
|
247
|
+
}
|
|
158
248
|
}
|
|
159
249
|
}
|
|
160
250
|
await log_1.LogService.append({
|
|
@@ -187,6 +277,42 @@ class TagCommand {
|
|
|
187
277
|
const normalized = answer.trim().toLowerCase();
|
|
188
278
|
return normalized === 'y' || normalized === 'yes';
|
|
189
279
|
}
|
|
280
|
+
async confirmTagDelete(tagName) {
|
|
281
|
+
const rl = readline_1.default.createInterface({
|
|
282
|
+
input: process.stdin,
|
|
283
|
+
output: process.stdout
|
|
284
|
+
});
|
|
285
|
+
const answer = await new Promise(resolve => {
|
|
286
|
+
rl.question(`Delete existing tag ${tagName} and create a new one? (y/n): `, resolve);
|
|
287
|
+
});
|
|
288
|
+
rl.close();
|
|
289
|
+
const normalized = answer.trim().toLowerCase();
|
|
290
|
+
return normalized === 'y' || normalized === 'yes';
|
|
291
|
+
}
|
|
292
|
+
async confirmRemoteTagDelete(tagName) {
|
|
293
|
+
const rl = readline_1.default.createInterface({
|
|
294
|
+
input: process.stdin,
|
|
295
|
+
output: process.stdout
|
|
296
|
+
});
|
|
297
|
+
const answer = await new Promise(resolve => {
|
|
298
|
+
rl.question(`Also delete remote tag ${tagName}? (y/n): `, resolve);
|
|
299
|
+
});
|
|
300
|
+
rl.close();
|
|
301
|
+
const normalized = answer.trim().toLowerCase();
|
|
302
|
+
return normalized === 'y' || normalized === 'yes';
|
|
303
|
+
}
|
|
304
|
+
async confirmForcePush(tagName) {
|
|
305
|
+
const rl = readline_1.default.createInterface({
|
|
306
|
+
input: process.stdin,
|
|
307
|
+
output: process.stdout
|
|
308
|
+
});
|
|
309
|
+
const answer = await new Promise(resolve => {
|
|
310
|
+
rl.question(`Force push tag ${tagName} to remote? (y/n): `, resolve);
|
|
311
|
+
});
|
|
312
|
+
rl.close();
|
|
313
|
+
const normalized = answer.trim().toLowerCase();
|
|
314
|
+
return normalized === 'y' || normalized === 'yes';
|
|
315
|
+
}
|
|
190
316
|
getCommand() {
|
|
191
317
|
return this.program;
|
|
192
318
|
}
|
package/dist/commands/tag.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tag.js","sourceRoot":"","sources":["../../src/commands/tag.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tag.js","sourceRoot":"","sources":["../../src/commands/tag.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/prompts/commit.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/C,eAAO,MAAM,oBAAoB,GAC/B,YAAY,MAAM,EAClB,2BAAuB,EACvB,WAAU,oBAA2B,KACpC,
|
|
1
|
+
{"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/prompts/commit.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/C,eAAO,MAAM,oBAAoB,GAC/B,YAAY,MAAM,EAClB,2BAAuB,EACvB,WAAU,oBAA2B,KACpC,MAoGF,CAAC"}
|
package/dist/prompts/commit.js
CHANGED
|
@@ -40,7 +40,9 @@ ${customInstructions}
|
|
|
40
40
|
## CRITICAL: Commit Message Output Rules
|
|
41
41
|
- DO NOT include any memory bank status indicators like "[Memory Bank: Active]" or "[Memory Bank: Missing]"
|
|
42
42
|
- DO NOT include any task-specific formatting or artifacts from other rules
|
|
43
|
+
- DO NOT use any Markdown styling (no **bold**, __underline__, \`code\`, links, or emojis) in the commit header, body, or footer
|
|
43
44
|
- ONLY Generate a clean conventional commit message as specified below
|
|
45
|
+
- Output exactly ONE conventional commit message. Choose a single primary type; never return multiple headers or multiple type prefixes.
|
|
44
46
|
|
|
45
47
|
${gitContext}
|
|
46
48
|
|
|
@@ -86,7 +88,7 @@ ${footerGuidelines}
|
|
|
86
88
|
|
|
87
89
|
## Analysis Instructions
|
|
88
90
|
When analyzing staged changes:
|
|
89
|
-
1. Determine Primary Type based on the nature of changes
|
|
91
|
+
1. Determine a single Primary Type based on the dominant nature of the changes (if multiple types apply, pick the most impactful one and stick to it)
|
|
90
92
|
2. Identify Scope from modified directories or modules
|
|
91
93
|
3. Craft Description focusing on the most significant change
|
|
92
94
|
4. Determine if there are Breaking Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/prompts/commit.ts"],"names":[],"mappings":";;;AAEO,MAAM,oBAAoB,GAAG,CAClC,UAAkB,EAClB,kBAAkB,GAAG,EAAE,EACvB,WAAiC,IAAI,EAC7B,EAAE;IACV,MAAM,mBAAmB,GAAG,QAAQ,KAAK,IAAI;QAC3C,CAAC,CAAC;;;+BAGyB;QAC3B,CAAC,CAAC;;;yCAGmC,CAAC;IAExC,MAAM,cAAc,GAAG,QAAQ,KAAK,IAAI;QACtC,CAAC,CAAC;;;;;;uCAMiC;QACnC,CAAC,CAAC;;;;mEAI6D,CAAC;IAElE,MAAM,gBAAgB,GAAG,QAAQ,KAAK,IAAI;QACxC,CAAC,CAAC;;yDAEmD;QACrD,CAAC,CAAC;;yDAEmD,CAAC;IAExD,OAAO;;;;EAIP,kBAAkB
|
|
1
|
+
{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/prompts/commit.ts"],"names":[],"mappings":";;;AAEO,MAAM,oBAAoB,GAAG,CAClC,UAAkB,EAClB,kBAAkB,GAAG,EAAE,EACvB,WAAiC,IAAI,EAC7B,EAAE;IACV,MAAM,mBAAmB,GAAG,QAAQ,KAAK,IAAI;QAC3C,CAAC,CAAC;;;+BAGyB;QAC3B,CAAC,CAAC;;;yCAGmC,CAAC;IAExC,MAAM,cAAc,GAAG,QAAQ,KAAK,IAAI;QACtC,CAAC,CAAC;;;;;;uCAMiC;QACnC,CAAC,CAAC;;;;mEAI6D,CAAC;IAElE,MAAM,gBAAgB,GAAG,QAAQ,KAAK,IAAI;QACxC,CAAC,CAAC;;yDAEmD;QACrD,CAAC,CAAC;;yDAEmD,CAAC;IAExD,OAAO;;;;EAIP,kBAAkB;;;;;;;;;EASlB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCV,mBAAmB;;EAEnB,cAAc;;EAEd,gBAAgB;;;;;;;;;;;;;yEAauD,CAAC;AAC1E,CAAC,CAAC;AAxGW,QAAA,oBAAoB,wBAwG/B"}
|
package/package.json
CHANGED
package/src/__tests__/ai.test.ts
CHANGED
|
@@ -104,6 +104,44 @@ describe('AIService', () => {
|
|
|
104
104
|
});
|
|
105
105
|
});
|
|
106
106
|
|
|
107
|
+
it('should strip markdown formatting from commit header', async () => {
|
|
108
|
+
const mockResponse = {
|
|
109
|
+
choices: [{
|
|
110
|
+
message: {
|
|
111
|
+
content: '**chore(track_object): 불필요한 줄바꿈 제거하여 가독성 개선**'
|
|
112
|
+
}
|
|
113
|
+
}]
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
(mockOpenai.chat.completions.create as jest.Mock).mockResolvedValue(mockResponse);
|
|
117
|
+
|
|
118
|
+
const result = await aiService.generateCommitMessage('diff --git a/file b/file');
|
|
119
|
+
|
|
120
|
+
expect(result).toEqual({
|
|
121
|
+
success: true,
|
|
122
|
+
message: 'chore(track_object): 불필요한 줄바꿈 제거하여 가독성 개선'
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should keep only the first commit header when multiple are returned', async () => {
|
|
127
|
+
const mockResponse = {
|
|
128
|
+
choices: [{
|
|
129
|
+
message: {
|
|
130
|
+
content: 'feat: add payment API\nchore: update dependencies'
|
|
131
|
+
}
|
|
132
|
+
}]
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
(mockOpenai.chat.completions.create as jest.Mock).mockResolvedValue(mockResponse);
|
|
136
|
+
|
|
137
|
+
const result = await aiService.generateCommitMessage('diff --git a/file b/file');
|
|
138
|
+
|
|
139
|
+
expect(result).toEqual({
|
|
140
|
+
success: true,
|
|
141
|
+
message: 'feat: add payment API'
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
107
145
|
it('should use default model when not specified', () => {
|
|
108
146
|
const aiServiceWithDefaults = new AIService({
|
|
109
147
|
apiKey: 'test-api-key'
|
|
@@ -7,11 +7,21 @@ jest.mock('../commands/git', () => {
|
|
|
7
7
|
diff: 'mock diff'
|
|
8
8
|
});
|
|
9
9
|
const createCommit = jest.fn().mockResolvedValue(true);
|
|
10
|
+
const tagExists = jest.fn().mockResolvedValue(false);
|
|
11
|
+
const remoteTagExists = jest.fn().mockResolvedValue(false);
|
|
12
|
+
const deleteLocalTag = jest.fn().mockResolvedValue(true);
|
|
13
|
+
const deleteRemoteTag = jest.fn().mockResolvedValue(true);
|
|
14
|
+
const forcePushTag = jest.fn().mockResolvedValue(true);
|
|
10
15
|
|
|
11
16
|
return {
|
|
12
17
|
GitService: {
|
|
13
18
|
getStagedDiff,
|
|
14
|
-
createCommit
|
|
19
|
+
createCommit,
|
|
20
|
+
tagExists,
|
|
21
|
+
remoteTagExists,
|
|
22
|
+
deleteLocalTag,
|
|
23
|
+
deleteRemoteTag,
|
|
24
|
+
forcePushTag
|
|
15
25
|
}
|
|
16
26
|
};
|
|
17
27
|
});
|
|
@@ -85,4 +95,94 @@ describe('GitService', () => {
|
|
|
85
95
|
expect(result).toBe(false);
|
|
86
96
|
});
|
|
87
97
|
});
|
|
98
|
+
|
|
99
|
+
describe('tagExists', () => {
|
|
100
|
+
it('should return true when tag exists locally', async () => {
|
|
101
|
+
(GitService.tagExists as jest.Mock).mockResolvedValueOnce(true);
|
|
102
|
+
|
|
103
|
+
const result = await GitService.tagExists('v1.0.0');
|
|
104
|
+
|
|
105
|
+
expect(result).toBe(true);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should return false when tag does not exist locally', async () => {
|
|
109
|
+
(GitService.tagExists as jest.Mock).mockResolvedValueOnce(false);
|
|
110
|
+
|
|
111
|
+
const result = await GitService.tagExists('v1.0.0');
|
|
112
|
+
|
|
113
|
+
expect(result).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe('remoteTagExists', () => {
|
|
118
|
+
it('should return true when tag exists on remote', async () => {
|
|
119
|
+
(GitService.remoteTagExists as jest.Mock).mockResolvedValueOnce(true);
|
|
120
|
+
|
|
121
|
+
const result = await GitService.remoteTagExists('v1.0.0');
|
|
122
|
+
|
|
123
|
+
expect(result).toBe(true);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should return false when tag does not exist on remote', async () => {
|
|
127
|
+
(GitService.remoteTagExists as jest.Mock).mockResolvedValueOnce(false);
|
|
128
|
+
|
|
129
|
+
const result = await GitService.remoteTagExists('v1.0.0');
|
|
130
|
+
|
|
131
|
+
expect(result).toBe(false);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe('deleteLocalTag', () => {
|
|
136
|
+
it('should return true when local tag is deleted successfully', async () => {
|
|
137
|
+
(GitService.deleteLocalTag as jest.Mock).mockResolvedValueOnce(true);
|
|
138
|
+
|
|
139
|
+
const result = await GitService.deleteLocalTag('v1.0.0');
|
|
140
|
+
|
|
141
|
+
expect(result).toBe(true);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('should return false when local tag deletion fails', async () => {
|
|
145
|
+
(GitService.deleteLocalTag as jest.Mock).mockResolvedValueOnce(false);
|
|
146
|
+
|
|
147
|
+
const result = await GitService.deleteLocalTag('v1.0.0');
|
|
148
|
+
|
|
149
|
+
expect(result).toBe(false);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
describe('deleteRemoteTag', () => {
|
|
154
|
+
it('should return true when remote tag is deleted successfully', async () => {
|
|
155
|
+
(GitService.deleteRemoteTag as jest.Mock).mockResolvedValueOnce(true);
|
|
156
|
+
|
|
157
|
+
const result = await GitService.deleteRemoteTag('v1.0.0');
|
|
158
|
+
|
|
159
|
+
expect(result).toBe(true);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('should return false when remote tag deletion fails', async () => {
|
|
163
|
+
(GitService.deleteRemoteTag as jest.Mock).mockResolvedValueOnce(false);
|
|
164
|
+
|
|
165
|
+
const result = await GitService.deleteRemoteTag('v1.0.0');
|
|
166
|
+
|
|
167
|
+
expect(result).toBe(false);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
describe('forcePushTag', () => {
|
|
172
|
+
it('should return true when force push is successful', async () => {
|
|
173
|
+
(GitService.forcePushTag as jest.Mock).mockResolvedValueOnce(true);
|
|
174
|
+
|
|
175
|
+
const result = await GitService.forcePushTag('v1.0.0');
|
|
176
|
+
|
|
177
|
+
expect(result).toBe(true);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should return false when force push fails', async () => {
|
|
181
|
+
(GitService.forcePushTag as jest.Mock).mockResolvedValueOnce(false);
|
|
182
|
+
|
|
183
|
+
const result = await GitService.forcePushTag('v1.0.0');
|
|
184
|
+
|
|
185
|
+
expect(result).toBe(false);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
88
188
|
});
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { CommitCommand } from '../commands/commit';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { spawn } from 'child_process';
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
|
|
7
|
+
// Mock dependencies
|
|
8
|
+
jest.mock('fs');
|
|
9
|
+
jest.mock('child_process', () => ({
|
|
10
|
+
spawn: jest.fn()
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
jest.mock('../commands/git', () => ({
|
|
14
|
+
GitService: {
|
|
15
|
+
getStagedDiff: jest.fn().mockResolvedValue({ success: true, diff: 'diff' }),
|
|
16
|
+
createCommit: jest.fn().mockResolvedValue(true),
|
|
17
|
+
push: jest.fn().mockResolvedValue(true)
|
|
18
|
+
}
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
jest.mock('../commands/ai', () => ({
|
|
22
|
+
AIService: jest.fn().mockImplementation(() => ({
|
|
23
|
+
generateCommitMessage: jest.fn().mockResolvedValue({ success: true, message: 'test commit' })
|
|
24
|
+
}))
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
jest.mock('../commands/config', () => ({
|
|
28
|
+
ConfigService: {
|
|
29
|
+
getConfig: jest.fn().mockReturnValue({ apiKey: 'key', language: 'en' }),
|
|
30
|
+
validateConfig: jest.fn()
|
|
31
|
+
}
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
jest.mock('../commands/log', () => ({
|
|
35
|
+
LogService: {
|
|
36
|
+
append: jest.fn().mockResolvedValue(undefined)
|
|
37
|
+
}
|
|
38
|
+
}));
|
|
39
|
+
|
|
40
|
+
describe('Pre-commit Hook Tests', () => {
|
|
41
|
+
let command: CommitCommand;
|
|
42
|
+
let mockSpawn: jest.Mock;
|
|
43
|
+
let mockFsExists: jest.Mock;
|
|
44
|
+
let mockFsRead: jest.Mock;
|
|
45
|
+
|
|
46
|
+
beforeEach(() => {
|
|
47
|
+
jest.clearAllMocks();
|
|
48
|
+
command = new CommitCommand();
|
|
49
|
+
|
|
50
|
+
mockSpawn = spawn as unknown as jest.Mock;
|
|
51
|
+
mockFsExists = fs.existsSync as unknown as jest.Mock;
|
|
52
|
+
mockFsRead = fs.readFileSync as unknown as jest.Mock;
|
|
53
|
+
|
|
54
|
+
// Default: no hooks found
|
|
55
|
+
mockFsExists.mockReturnValue(false);
|
|
56
|
+
|
|
57
|
+
// Default spawn behavior: succeed immediately
|
|
58
|
+
mockSpawn.mockImplementation((cmd, args) => {
|
|
59
|
+
console.log(`Mock spawn called: ${cmd} ${args}`);
|
|
60
|
+
const child = new EventEmitter();
|
|
61
|
+
(child as any).stdout = new EventEmitter();
|
|
62
|
+
(child as any).stderr = new EventEmitter();
|
|
63
|
+
setTimeout(() => {
|
|
64
|
+
child.emit('close', 0);
|
|
65
|
+
}, 10);
|
|
66
|
+
return child;
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should run npm pre-commit script if present', async () => {
|
|
71
|
+
mockFsExists.mockImplementation((p: string) => p.endsWith('package.json'));
|
|
72
|
+
mockFsRead.mockReturnValue(JSON.stringify({
|
|
73
|
+
scripts: {
|
|
74
|
+
'pre-commit': 'echo test'
|
|
75
|
+
}
|
|
76
|
+
}));
|
|
77
|
+
|
|
78
|
+
jest.spyOn(command as any, 'confirmCommit').mockResolvedValue(true);
|
|
79
|
+
|
|
80
|
+
await (command as any).handleCommit({});
|
|
81
|
+
|
|
82
|
+
expect(mockSpawn).toHaveBeenCalledWith('npm', ['run', 'pre-commit'], expect.anything());
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should run pre-commit hooks if .pre-commit-config.yaml is present', async () => {
|
|
86
|
+
mockFsExists.mockImplementation((p: string) => p.endsWith('.pre-commit-config.yaml'));
|
|
87
|
+
|
|
88
|
+
jest.spyOn(command as any, 'confirmCommit').mockResolvedValue(true);
|
|
89
|
+
|
|
90
|
+
await (command as any).handleCommit({});
|
|
91
|
+
|
|
92
|
+
expect(mockSpawn).toHaveBeenCalledWith('pre-commit', ['run'], expect.anything());
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should fail commit if npm pre-commit script fails', async () => {
|
|
96
|
+
mockFsExists.mockImplementation((p: string) => p.endsWith('package.json'));
|
|
97
|
+
mockFsRead.mockReturnValue(JSON.stringify({
|
|
98
|
+
scripts: { 'pre-commit': 'fail' }
|
|
99
|
+
}));
|
|
100
|
+
|
|
101
|
+
mockSpawn.mockImplementation(() => {
|
|
102
|
+
const child = new EventEmitter();
|
|
103
|
+
setTimeout(() => child.emit('close', 1), 10);
|
|
104
|
+
return child;
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const exitSpy = jest.spyOn(process, 'exit').mockImplementation((() => {}) as any);
|
|
108
|
+
|
|
109
|
+
await (command as any).handleCommit({});
|
|
110
|
+
|
|
111
|
+
expect(mockSpawn).toHaveBeenCalled();
|
|
112
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should fail commit if pre-commit hooks fail', async () => {
|
|
116
|
+
mockFsExists.mockImplementation((p: string) => p.endsWith('.pre-commit-config.yaml'));
|
|
117
|
+
|
|
118
|
+
mockSpawn.mockImplementation(() => {
|
|
119
|
+
const child = new EventEmitter();
|
|
120
|
+
setTimeout(() => child.emit('close', 1), 10);
|
|
121
|
+
return child;
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const exitSpy = jest.spyOn(process, 'exit').mockImplementation((() => {}) as any);
|
|
125
|
+
|
|
126
|
+
await (command as any).handleCommit({});
|
|
127
|
+
|
|
128
|
+
expect(mockSpawn).toHaveBeenCalled();
|
|
129
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should run both hooks if both exist', async () => {
|
|
133
|
+
mockFsExists.mockReturnValue(true);
|
|
134
|
+
mockFsRead.mockReturnValue(JSON.stringify({
|
|
135
|
+
scripts: { 'pre-commit': 'test' }
|
|
136
|
+
}));
|
|
137
|
+
|
|
138
|
+
jest.spyOn(command as any, 'confirmCommit').mockResolvedValue(true);
|
|
139
|
+
|
|
140
|
+
await (command as any).handleCommit({});
|
|
141
|
+
|
|
142
|
+
expect(mockSpawn).toHaveBeenCalledTimes(2);
|
|
143
|
+
expect(mockSpawn).toHaveBeenCalledWith('npm', ['run', 'pre-commit'], expect.anything());
|
|
144
|
+
expect(mockSpawn).toHaveBeenCalledWith('pre-commit', ['run'], expect.anything());
|
|
145
|
+
});
|
|
146
|
+
});
|