@m3hti/commit-genie 1.0.0
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/LICENSE +21 -0
- package/README.md +430 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +31 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/generate.d.ts +10 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +313 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/generate.test.d.ts +2 -0
- package/dist/commands/generate.test.d.ts.map +1 -0
- package/dist/commands/generate.test.js +168 -0
- package/dist/commands/generate.test.js.map +1 -0
- package/dist/commands/hook.d.ts +4 -0
- package/dist/commands/hook.d.ts.map +1 -0
- package/dist/commands/hook.js +62 -0
- package/dist/commands/hook.js.map +1 -0
- package/dist/commands/stats.d.ts +6 -0
- package/dist/commands/stats.d.ts.map +1 -0
- package/dist/commands/stats.js +39 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -0
- package/dist/index.js.map +1 -0
- package/dist/services/aiService.d.ts +38 -0
- package/dist/services/aiService.d.ts.map +1 -0
- package/dist/services/aiService.js +187 -0
- package/dist/services/aiService.js.map +1 -0
- package/dist/services/analyzerService.d.ts +60 -0
- package/dist/services/analyzerService.d.ts.map +1 -0
- package/dist/services/analyzerService.js +832 -0
- package/dist/services/analyzerService.js.map +1 -0
- package/dist/services/analyzerService.test.d.ts +2 -0
- package/dist/services/analyzerService.test.d.ts.map +1 -0
- package/dist/services/analyzerService.test.js +323 -0
- package/dist/services/analyzerService.test.js.map +1 -0
- package/dist/services/configService.d.ts +25 -0
- package/dist/services/configService.d.ts.map +1 -0
- package/dist/services/configService.js +207 -0
- package/dist/services/configService.js.map +1 -0
- package/dist/services/configService.test.d.ts +2 -0
- package/dist/services/configService.test.d.ts.map +1 -0
- package/dist/services/configService.test.js +165 -0
- package/dist/services/configService.test.js.map +1 -0
- package/dist/services/gitService.d.ts +44 -0
- package/dist/services/gitService.d.ts.map +1 -0
- package/dist/services/gitService.js +217 -0
- package/dist/services/gitService.js.map +1 -0
- package/dist/services/gitService.test.d.ts +2 -0
- package/dist/services/gitService.test.d.ts.map +1 -0
- package/dist/services/gitService.test.js +140 -0
- package/dist/services/gitService.test.js.map +1 -0
- package/dist/services/historyService.d.ts +39 -0
- package/dist/services/historyService.d.ts.map +1 -0
- package/dist/services/historyService.js +195 -0
- package/dist/services/historyService.js.map +1 -0
- package/dist/services/historyService.test.d.ts +2 -0
- package/dist/services/historyService.test.d.ts.map +1 -0
- package/dist/services/historyService.test.js +157 -0
- package/dist/services/historyService.test.js.map +1 -0
- package/dist/services/hookService.d.ts +29 -0
- package/dist/services/hookService.d.ts.map +1 -0
- package/dist/services/hookService.js +164 -0
- package/dist/services/hookService.js.map +1 -0
- package/dist/services/statsService.d.ts +28 -0
- package/dist/services/statsService.d.ts.map +1 -0
- package/dist/services/statsService.js +204 -0
- package/dist/services/statsService.js.map +1 -0
- package/dist/types/index.d.ts +134 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/filePatterns.d.ts +5 -0
- package/dist/utils/filePatterns.d.ts.map +1 -0
- package/dist/utils/filePatterns.js +77 -0
- package/dist/utils/filePatterns.js.map +1 -0
- package/dist/utils/filePatterns.test.d.ts +2 -0
- package/dist/utils/filePatterns.test.d.ts.map +1 -0
- package/dist/utils/filePatterns.test.js +51 -0
- package/dist/utils/filePatterns.test.js.map +1 -0
- package/dist/utils/prompt.d.ts +4 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +60 -0
- package/dist/utils/prompt.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { TicketInfo, CommitHistoryAnalysis, CommitType } from '../types';
|
|
2
|
+
export declare class HistoryService {
|
|
3
|
+
private static cachedAnalysis;
|
|
4
|
+
private static cacheTimestamp;
|
|
5
|
+
private static CACHE_TTL;
|
|
6
|
+
/**
|
|
7
|
+
* Detect ticket/issue reference from branch name
|
|
8
|
+
*/
|
|
9
|
+
static detectTicketFromBranch(): TicketInfo | null;
|
|
10
|
+
/**
|
|
11
|
+
* Analyze commit history to learn project patterns
|
|
12
|
+
*/
|
|
13
|
+
static analyzeCommitHistory(): CommitHistoryAnalysis;
|
|
14
|
+
/**
|
|
15
|
+
* Perform the actual analysis on commits
|
|
16
|
+
*/
|
|
17
|
+
private static performAnalysis;
|
|
18
|
+
/**
|
|
19
|
+
* Get default analysis when no history is available
|
|
20
|
+
*/
|
|
21
|
+
private static getDefaultAnalysis;
|
|
22
|
+
/**
|
|
23
|
+
* Get the most common commit type from history
|
|
24
|
+
*/
|
|
25
|
+
static getMostCommonType(): CommitType | null;
|
|
26
|
+
/**
|
|
27
|
+
* Check if project historically uses emojis
|
|
28
|
+
*/
|
|
29
|
+
static projectUsesEmojis(): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Get suggested scope based on history
|
|
32
|
+
*/
|
|
33
|
+
static getSuggestedScope(filePaths: string[]): string | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Clear the cached analysis
|
|
36
|
+
*/
|
|
37
|
+
static clearCache(): void;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=historyService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"historyService.d.ts","sourceRoot":"","sources":["../../src/services/historyService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAoB,UAAU,EAAE,MAAM,UAAU,CAAC;AAe3F,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAsC;IACnE,OAAO,CAAC,MAAM,CAAC,cAAc,CAAa;IAC1C,OAAO,CAAC,MAAM,CAAC,SAAS,CAAS;IAEjC;;OAEG;IACH,MAAM,CAAC,sBAAsB,IAAI,UAAU,GAAG,IAAI;IA8BlD;;OAEG;IACH,MAAM,CAAC,oBAAoB,IAAI,qBAAqB;IA+BpD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAqE9B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAYjC;;OAEG;IACH,MAAM,CAAC,iBAAiB,IAAI,UAAU,GAAG,IAAI;IAU7C;;OAEG;IACH,MAAM,CAAC,iBAAiB,IAAI,OAAO;IAKnC;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS;IAkBjE;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,IAAI;CAI1B"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HistoryService = void 0;
|
|
4
|
+
const gitService_1 = require("./gitService");
|
|
5
|
+
const configService_1 = require("./configService");
|
|
6
|
+
// Common ticket patterns for various issue trackers
|
|
7
|
+
const DEFAULT_TICKET_PATTERNS = [
|
|
8
|
+
/([A-Z]{2,10}-\d+)/g, // JIRA-style: ABC-123, PROJ-1234
|
|
9
|
+
/#(\d+)/g, // GitHub/GitLab: #123
|
|
10
|
+
/([A-Z]{2,10}_\d+)/g, // Underscore style: ABC_123
|
|
11
|
+
];
|
|
12
|
+
// Common emojis used in commit messages
|
|
13
|
+
const EMOJI_PATTERN = /^[\u{1F300}-\u{1F9FF}]|^[\u{2600}-\u{26FF}]|^[\u{2700}-\u{27BF}]|^:[\w+-]+:/u;
|
|
14
|
+
// Conventional commit pattern
|
|
15
|
+
const CONVENTIONAL_COMMIT_PATTERN = /^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?!?:/i;
|
|
16
|
+
class HistoryService {
|
|
17
|
+
/**
|
|
18
|
+
* Detect ticket/issue reference from branch name
|
|
19
|
+
*/
|
|
20
|
+
static detectTicketFromBranch() {
|
|
21
|
+
const config = configService_1.ConfigService.getConfig();
|
|
22
|
+
const ticketConfig = config.ticketLinking;
|
|
23
|
+
// Check if ticket linking is disabled
|
|
24
|
+
if (ticketConfig?.enabled === false) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const branch = gitService_1.GitService.getCurrentBranch();
|
|
28
|
+
if (!branch)
|
|
29
|
+
return null;
|
|
30
|
+
// Use custom patterns if provided, otherwise use defaults
|
|
31
|
+
const patterns = ticketConfig?.patterns?.map(p => new RegExp(p, 'g')) || DEFAULT_TICKET_PATTERNS;
|
|
32
|
+
for (const pattern of patterns) {
|
|
33
|
+
pattern.lastIndex = 0; // Reset regex state
|
|
34
|
+
const match = pattern.exec(branch);
|
|
35
|
+
if (match) {
|
|
36
|
+
return {
|
|
37
|
+
id: match[1] || match[0],
|
|
38
|
+
source: 'branch',
|
|
39
|
+
prefix: ticketConfig?.prefix || 'Refs:',
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Analyze commit history to learn project patterns
|
|
47
|
+
*/
|
|
48
|
+
static analyzeCommitHistory() {
|
|
49
|
+
const config = configService_1.ConfigService.getConfig();
|
|
50
|
+
const historyConfig = config.learnFromHistory;
|
|
51
|
+
// Check if history learning is disabled
|
|
52
|
+
if (historyConfig?.enabled === false) {
|
|
53
|
+
return this.getDefaultAnalysis();
|
|
54
|
+
}
|
|
55
|
+
// Return cached analysis if still valid
|
|
56
|
+
const now = Date.now();
|
|
57
|
+
if (this.cachedAnalysis && (now - this.cacheTimestamp) < this.CACHE_TTL) {
|
|
58
|
+
return this.cachedAnalysis;
|
|
59
|
+
}
|
|
60
|
+
const commitCount = historyConfig?.commitCount || 50;
|
|
61
|
+
const commits = gitService_1.GitService.getCommitHistory(commitCount);
|
|
62
|
+
if (commits.length === 0) {
|
|
63
|
+
return this.getDefaultAnalysis();
|
|
64
|
+
}
|
|
65
|
+
const analysis = this.performAnalysis(commits);
|
|
66
|
+
// Cache the result
|
|
67
|
+
this.cachedAnalysis = analysis;
|
|
68
|
+
this.cacheTimestamp = now;
|
|
69
|
+
return analysis;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Perform the actual analysis on commits
|
|
73
|
+
*/
|
|
74
|
+
static performAnalysis(commits) {
|
|
75
|
+
let emojiCount = 0;
|
|
76
|
+
let conventionalCount = 0;
|
|
77
|
+
let totalLength = 0;
|
|
78
|
+
const scopeCount = {};
|
|
79
|
+
const verbCount = {};
|
|
80
|
+
const emojiFrequency = {};
|
|
81
|
+
const typeFrequency = {};
|
|
82
|
+
for (const commit of commits) {
|
|
83
|
+
const subject = commit.subject;
|
|
84
|
+
totalLength += subject.length;
|
|
85
|
+
// Check for emojis
|
|
86
|
+
const emojiMatch = subject.match(EMOJI_PATTERN);
|
|
87
|
+
if (emojiMatch) {
|
|
88
|
+
emojiCount++;
|
|
89
|
+
const emoji = emojiMatch[0];
|
|
90
|
+
emojiFrequency[emoji] = (emojiFrequency[emoji] || 0) + 1;
|
|
91
|
+
}
|
|
92
|
+
// Check for conventional commits
|
|
93
|
+
const conventionalMatch = subject.match(CONVENTIONAL_COMMIT_PATTERN);
|
|
94
|
+
if (conventionalMatch) {
|
|
95
|
+
conventionalCount++;
|
|
96
|
+
const type = conventionalMatch[1].toLowerCase();
|
|
97
|
+
typeFrequency[type] = (typeFrequency[type] || 0) + 1;
|
|
98
|
+
// Extract scope if present
|
|
99
|
+
if (conventionalMatch[2]) {
|
|
100
|
+
const scope = conventionalMatch[2].replace(/[()]/g, '');
|
|
101
|
+
scopeCount[scope] = (scopeCount[scope] || 0) + 1;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Extract common verbs (first word after type or emoji)
|
|
105
|
+
const cleanSubject = subject
|
|
106
|
+
.replace(EMOJI_PATTERN, '')
|
|
107
|
+
.replace(CONVENTIONAL_COMMIT_PATTERN, '')
|
|
108
|
+
.trim();
|
|
109
|
+
const firstWord = cleanSubject.split(/\s+/)[0]?.toLowerCase();
|
|
110
|
+
if (firstWord && firstWord.length > 2 && /^[a-z]+$/.test(firstWord)) {
|
|
111
|
+
verbCount[firstWord] = (verbCount[firstWord] || 0) + 1;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Sort and get top items
|
|
115
|
+
const sortedScopes = Object.entries(scopeCount)
|
|
116
|
+
.sort((a, b) => b[1] - a[1])
|
|
117
|
+
.slice(0, 10)
|
|
118
|
+
.map(([scope]) => scope);
|
|
119
|
+
const sortedVerbs = Object.entries(verbCount)
|
|
120
|
+
.sort((a, b) => b[1] - a[1])
|
|
121
|
+
.slice(0, 10)
|
|
122
|
+
.map(([verb]) => verb);
|
|
123
|
+
return {
|
|
124
|
+
usesEmojis: emojiCount > commits.length * 0.3, // 30% threshold
|
|
125
|
+
usesConventionalCommits: conventionalCount > commits.length * 0.5, // 50% threshold
|
|
126
|
+
commonScopes: sortedScopes,
|
|
127
|
+
commonVerbs: sortedVerbs,
|
|
128
|
+
averageLength: Math.round(totalLength / commits.length),
|
|
129
|
+
emojiFrequency,
|
|
130
|
+
typeFrequency,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get default analysis when no history is available
|
|
135
|
+
*/
|
|
136
|
+
static getDefaultAnalysis() {
|
|
137
|
+
return {
|
|
138
|
+
usesEmojis: true, // Default to current behavior
|
|
139
|
+
usesConventionalCommits: true,
|
|
140
|
+
commonScopes: [],
|
|
141
|
+
commonVerbs: ['add', 'update', 'fix', 'remove', 'refactor'],
|
|
142
|
+
averageLength: 50,
|
|
143
|
+
emojiFrequency: {},
|
|
144
|
+
typeFrequency: {},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get the most common commit type from history
|
|
149
|
+
*/
|
|
150
|
+
static getMostCommonType() {
|
|
151
|
+
const analysis = this.analyzeCommitHistory();
|
|
152
|
+
const types = Object.entries(analysis.typeFrequency);
|
|
153
|
+
if (types.length === 0)
|
|
154
|
+
return null;
|
|
155
|
+
types.sort((a, b) => b[1] - a[1]);
|
|
156
|
+
return types[0][0];
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Check if project historically uses emojis
|
|
160
|
+
*/
|
|
161
|
+
static projectUsesEmojis() {
|
|
162
|
+
const analysis = this.analyzeCommitHistory();
|
|
163
|
+
return analysis.usesEmojis;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get suggested scope based on history
|
|
167
|
+
*/
|
|
168
|
+
static getSuggestedScope(filePaths) {
|
|
169
|
+
const analysis = this.analyzeCommitHistory();
|
|
170
|
+
if (analysis.commonScopes.length === 0)
|
|
171
|
+
return undefined;
|
|
172
|
+
// Try to match file paths with common scopes
|
|
173
|
+
for (const scope of analysis.commonScopes) {
|
|
174
|
+
const scopeLower = scope.toLowerCase();
|
|
175
|
+
for (const filePath of filePaths) {
|
|
176
|
+
if (filePath.toLowerCase().includes(scopeLower)) {
|
|
177
|
+
return scope;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Clear the cached analysis
|
|
185
|
+
*/
|
|
186
|
+
static clearCache() {
|
|
187
|
+
this.cachedAnalysis = null;
|
|
188
|
+
this.cacheTimestamp = 0;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
exports.HistoryService = HistoryService;
|
|
192
|
+
HistoryService.cachedAnalysis = null;
|
|
193
|
+
HistoryService.cacheTimestamp = 0;
|
|
194
|
+
HistoryService.CACHE_TTL = 60000; // 1 minute cache
|
|
195
|
+
//# sourceMappingURL=historyService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"historyService.js","sourceRoot":"","sources":["../../src/services/historyService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"historyService.test.d.ts","sourceRoot":"","sources":["../../src/services/historyService.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const historyService_1 = require("./historyService");
|
|
4
|
+
const gitService_1 = require("./gitService");
|
|
5
|
+
const configService_1 = require("./configService");
|
|
6
|
+
// Mock dependencies
|
|
7
|
+
jest.mock('./gitService');
|
|
8
|
+
jest.mock('./configService');
|
|
9
|
+
const mockedGitService = gitService_1.GitService;
|
|
10
|
+
const mockedConfigService = configService_1.ConfigService;
|
|
11
|
+
describe('HistoryService', () => {
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
jest.clearAllMocks();
|
|
14
|
+
historyService_1.HistoryService.clearCache();
|
|
15
|
+
// Default config mock
|
|
16
|
+
mockedConfigService.getConfig.mockReturnValue({
|
|
17
|
+
scopes: [],
|
|
18
|
+
defaultType: 'feat',
|
|
19
|
+
maxMessageLength: 72,
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
describe('detectTicketFromBranch', () => {
|
|
23
|
+
it('should detect JIRA-style tickets from branch name', () => {
|
|
24
|
+
mockedGitService.getCurrentBranch.mockReturnValue('feature/ABC-123-add-login');
|
|
25
|
+
const ticket = historyService_1.HistoryService.detectTicketFromBranch();
|
|
26
|
+
expect(ticket).not.toBeNull();
|
|
27
|
+
expect(ticket?.id).toBe('ABC-123');
|
|
28
|
+
expect(ticket?.source).toBe('branch');
|
|
29
|
+
});
|
|
30
|
+
it('should detect GitHub-style issue numbers from branch name', () => {
|
|
31
|
+
mockedGitService.getCurrentBranch.mockReturnValue('fix/#456-bug-fix');
|
|
32
|
+
const ticket = historyService_1.HistoryService.detectTicketFromBranch();
|
|
33
|
+
expect(ticket).not.toBeNull();
|
|
34
|
+
expect(ticket?.id).toBe('456');
|
|
35
|
+
});
|
|
36
|
+
it('should return null when no ticket found', () => {
|
|
37
|
+
mockedGitService.getCurrentBranch.mockReturnValue('feature/add-new-feature');
|
|
38
|
+
const ticket = historyService_1.HistoryService.detectTicketFromBranch();
|
|
39
|
+
expect(ticket).toBeNull();
|
|
40
|
+
});
|
|
41
|
+
it('should return null when ticket linking is disabled', () => {
|
|
42
|
+
mockedConfigService.getConfig.mockReturnValue({
|
|
43
|
+
scopes: [],
|
|
44
|
+
defaultType: 'feat',
|
|
45
|
+
maxMessageLength: 72,
|
|
46
|
+
ticketLinking: {
|
|
47
|
+
enabled: false,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
mockedGitService.getCurrentBranch.mockReturnValue('feature/ABC-123-add-login');
|
|
51
|
+
const ticket = historyService_1.HistoryService.detectTicketFromBranch();
|
|
52
|
+
expect(ticket).toBeNull();
|
|
53
|
+
});
|
|
54
|
+
it('should use custom patterns when provided', () => {
|
|
55
|
+
mockedConfigService.getConfig.mockReturnValue({
|
|
56
|
+
scopes: [],
|
|
57
|
+
defaultType: 'feat',
|
|
58
|
+
maxMessageLength: 72,
|
|
59
|
+
ticketLinking: {
|
|
60
|
+
enabled: true,
|
|
61
|
+
patterns: ['CUSTOM-(\\d+)'],
|
|
62
|
+
prefix: 'Fixes:',
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
mockedGitService.getCurrentBranch.mockReturnValue('feature/CUSTOM-999-task');
|
|
66
|
+
const ticket = historyService_1.HistoryService.detectTicketFromBranch();
|
|
67
|
+
expect(ticket).not.toBeNull();
|
|
68
|
+
expect(ticket?.id).toBe('999');
|
|
69
|
+
expect(ticket?.prefix).toBe('Fixes:');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('analyzeCommitHistory', () => {
|
|
73
|
+
it('should detect emoji usage in history', () => {
|
|
74
|
+
mockedGitService.getCommitHistory.mockReturnValue([
|
|
75
|
+
{ hash: '1', subject: '✨ feat: add feature', message: '✨ feat: add feature' },
|
|
76
|
+
{ hash: '2', subject: '🐛 fix: fix bug', message: '🐛 fix: fix bug' },
|
|
77
|
+
{ hash: '3', subject: '📚 docs: update readme', message: '📚 docs: update readme' },
|
|
78
|
+
]);
|
|
79
|
+
const analysis = historyService_1.HistoryService.analyzeCommitHistory();
|
|
80
|
+
expect(analysis.usesEmojis).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
it('should detect conventional commits', () => {
|
|
83
|
+
mockedGitService.getCommitHistory.mockReturnValue([
|
|
84
|
+
{ hash: '1', subject: 'feat: add feature', message: 'feat: add feature' },
|
|
85
|
+
{ hash: '2', subject: 'fix: fix bug', message: 'fix: fix bug' },
|
|
86
|
+
{ hash: '3', subject: 'docs: update readme', message: 'docs: update readme' },
|
|
87
|
+
]);
|
|
88
|
+
const analysis = historyService_1.HistoryService.analyzeCommitHistory();
|
|
89
|
+
expect(analysis.usesConventionalCommits).toBe(true);
|
|
90
|
+
});
|
|
91
|
+
it('should extract common scopes', () => {
|
|
92
|
+
mockedGitService.getCommitHistory.mockReturnValue([
|
|
93
|
+
{ hash: '1', subject: 'feat(api): add endpoint', message: 'feat(api): add endpoint' },
|
|
94
|
+
{ hash: '2', subject: 'fix(api): fix bug', message: 'fix(api): fix bug' },
|
|
95
|
+
{ hash: '3', subject: 'feat(ui): add button', message: 'feat(ui): add button' },
|
|
96
|
+
]);
|
|
97
|
+
const analysis = historyService_1.HistoryService.analyzeCommitHistory();
|
|
98
|
+
expect(analysis.commonScopes).toContain('api');
|
|
99
|
+
expect(analysis.commonScopes).toContain('ui');
|
|
100
|
+
});
|
|
101
|
+
it('should return default analysis when history is empty', () => {
|
|
102
|
+
mockedGitService.getCommitHistory.mockReturnValue([]);
|
|
103
|
+
const analysis = historyService_1.HistoryService.analyzeCommitHistory();
|
|
104
|
+
expect(analysis.usesEmojis).toBe(true);
|
|
105
|
+
expect(analysis.usesConventionalCommits).toBe(true);
|
|
106
|
+
});
|
|
107
|
+
it('should return default analysis when history learning is disabled', () => {
|
|
108
|
+
mockedConfigService.getConfig.mockReturnValue({
|
|
109
|
+
scopes: [],
|
|
110
|
+
defaultType: 'feat',
|
|
111
|
+
maxMessageLength: 72,
|
|
112
|
+
learnFromHistory: {
|
|
113
|
+
enabled: false,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
const analysis = historyService_1.HistoryService.analyzeCommitHistory();
|
|
117
|
+
expect(analysis.usesEmojis).toBe(true);
|
|
118
|
+
expect(analysis.usesConventionalCommits).toBe(true);
|
|
119
|
+
});
|
|
120
|
+
it('should cache analysis results', () => {
|
|
121
|
+
mockedGitService.getCommitHistory.mockReturnValue([
|
|
122
|
+
{ hash: '1', subject: 'feat: add feature', message: 'feat: add feature' },
|
|
123
|
+
]);
|
|
124
|
+
historyService_1.HistoryService.analyzeCommitHistory();
|
|
125
|
+
historyService_1.HistoryService.analyzeCommitHistory();
|
|
126
|
+
historyService_1.HistoryService.analyzeCommitHistory();
|
|
127
|
+
expect(mockedGitService.getCommitHistory).toHaveBeenCalledTimes(1);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
describe('projectUsesEmojis', () => {
|
|
131
|
+
it('should return true when project uses emojis', () => {
|
|
132
|
+
mockedGitService.getCommitHistory.mockReturnValue([
|
|
133
|
+
{ hash: '1', subject: '✨ feat: add feature', message: '✨ feat: add feature' },
|
|
134
|
+
{ hash: '2', subject: '🐛 fix: fix bug', message: '🐛 fix: fix bug' },
|
|
135
|
+
]);
|
|
136
|
+
expect(historyService_1.HistoryService.projectUsesEmojis()).toBe(true);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
describe('getSuggestedScope', () => {
|
|
140
|
+
it('should suggest scope based on file paths matching history', () => {
|
|
141
|
+
mockedGitService.getCommitHistory.mockReturnValue([
|
|
142
|
+
{ hash: '1', subject: 'feat(api): add endpoint', message: 'feat(api): add endpoint' },
|
|
143
|
+
{ hash: '2', subject: 'feat(api): update endpoint', message: 'feat(api): update endpoint' },
|
|
144
|
+
]);
|
|
145
|
+
const scope = historyService_1.HistoryService.getSuggestedScope(['src/api/users.ts']);
|
|
146
|
+
expect(scope).toBe('api');
|
|
147
|
+
});
|
|
148
|
+
it('should return undefined when no match found', () => {
|
|
149
|
+
mockedGitService.getCommitHistory.mockReturnValue([
|
|
150
|
+
{ hash: '1', subject: 'feat(api): add endpoint', message: 'feat(api): add endpoint' },
|
|
151
|
+
]);
|
|
152
|
+
const scope = historyService_1.HistoryService.getSuggestedScope(['src/utils/helper.ts']);
|
|
153
|
+
expect(scope).toBeUndefined();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
//# sourceMappingURL=historyService.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"historyService.test.js","sourceRoot":"","sources":["../../src/services/historyService.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare class HookService {
|
|
2
|
+
/**
|
|
3
|
+
* Get the path to the git hooks directory
|
|
4
|
+
*/
|
|
5
|
+
static getHooksDir(): string;
|
|
6
|
+
/**
|
|
7
|
+
* Get the path to the prepare-commit-msg hook
|
|
8
|
+
*/
|
|
9
|
+
static getHookPath(): string;
|
|
10
|
+
/**
|
|
11
|
+
* Check if the hook is already installed
|
|
12
|
+
*/
|
|
13
|
+
static isInstalled(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Install the prepare-commit-msg hook
|
|
16
|
+
*/
|
|
17
|
+
static install(): {
|
|
18
|
+
success: boolean;
|
|
19
|
+
message: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Uninstall the prepare-commit-msg hook
|
|
23
|
+
*/
|
|
24
|
+
static uninstall(): {
|
|
25
|
+
success: boolean;
|
|
26
|
+
message: string;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=hookService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hookService.d.ts","sourceRoot":"","sources":["../../src/services/hookService.ts"],"names":[],"mappings":"AAgCA,qBAAa,WAAW;IACtB;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,MAAM;IAK5B;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,MAAM;IAI5B;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,OAAO;IAS7B;;OAEG;IACH,MAAM,CAAC,OAAO,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAqCvD;;OAEG;IACH,MAAM,CAAC,SAAS,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAoC1D"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.HookService = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const gitService_1 = require("./gitService");
|
|
40
|
+
const HOOK_NAME = 'prepare-commit-msg';
|
|
41
|
+
const HOOK_SCRIPT = `#!/bin/sh
|
|
42
|
+
# CommitGenie prepare-commit-msg hook
|
|
43
|
+
# This hook generates a commit message suggestion
|
|
44
|
+
|
|
45
|
+
COMMIT_MSG_FILE=$1
|
|
46
|
+
COMMIT_SOURCE=$2
|
|
47
|
+
|
|
48
|
+
# Only run for regular commits (not merges, squashes, etc.)
|
|
49
|
+
if [ -z "$COMMIT_SOURCE" ]; then
|
|
50
|
+
# Check if commit-genie is available
|
|
51
|
+
if command -v commit-genie &> /dev/null; then
|
|
52
|
+
# Generate message and write to file
|
|
53
|
+
MESSAGE=$(commit-genie --message-only 2>/dev/null)
|
|
54
|
+
if [ -n "$MESSAGE" ]; then
|
|
55
|
+
echo "$MESSAGE" > "$COMMIT_MSG_FILE"
|
|
56
|
+
fi
|
|
57
|
+
elif command -v npx &> /dev/null; then
|
|
58
|
+
# Fallback to npx if commit-genie is not globally installed
|
|
59
|
+
MESSAGE=$(npx --yes commit-genie --message-only 2>/dev/null)
|
|
60
|
+
if [ -n "$MESSAGE" ]; then
|
|
61
|
+
echo "$MESSAGE" > "$COMMIT_MSG_FILE"
|
|
62
|
+
fi
|
|
63
|
+
fi
|
|
64
|
+
fi
|
|
65
|
+
`;
|
|
66
|
+
class HookService {
|
|
67
|
+
/**
|
|
68
|
+
* Get the path to the git hooks directory
|
|
69
|
+
*/
|
|
70
|
+
static getHooksDir() {
|
|
71
|
+
const gitDir = gitService_1.GitService.getGitDir();
|
|
72
|
+
return path.join(gitDir, 'hooks');
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get the path to the prepare-commit-msg hook
|
|
76
|
+
*/
|
|
77
|
+
static getHookPath() {
|
|
78
|
+
return path.join(this.getHooksDir(), HOOK_NAME);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check if the hook is already installed
|
|
82
|
+
*/
|
|
83
|
+
static isInstalled() {
|
|
84
|
+
const hookPath = this.getHookPath();
|
|
85
|
+
if (!fs.existsSync(hookPath)) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
const content = fs.readFileSync(hookPath, 'utf-8');
|
|
89
|
+
return content.includes('CommitGenie');
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Install the prepare-commit-msg hook
|
|
93
|
+
*/
|
|
94
|
+
static install() {
|
|
95
|
+
try {
|
|
96
|
+
const hookPath = this.getHookPath();
|
|
97
|
+
const hooksDir = this.getHooksDir();
|
|
98
|
+
// Ensure hooks directory exists
|
|
99
|
+
if (!fs.existsSync(hooksDir)) {
|
|
100
|
+
fs.mkdirSync(hooksDir, { recursive: true });
|
|
101
|
+
}
|
|
102
|
+
// Check if hook already exists
|
|
103
|
+
if (fs.existsSync(hookPath)) {
|
|
104
|
+
const existingContent = fs.readFileSync(hookPath, 'utf-8');
|
|
105
|
+
if (existingContent.includes('CommitGenie')) {
|
|
106
|
+
return { success: true, message: 'Hook is already installed.' };
|
|
107
|
+
}
|
|
108
|
+
// Backup existing hook
|
|
109
|
+
const backupPath = `${hookPath}.backup`;
|
|
110
|
+
fs.copyFileSync(hookPath, backupPath);
|
|
111
|
+
return {
|
|
112
|
+
success: false,
|
|
113
|
+
message: `Existing hook found. Backed up to ${backupPath}. Please manually integrate or remove the existing hook.`,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// Write the hook
|
|
117
|
+
fs.writeFileSync(hookPath, HOOK_SCRIPT, { mode: 0o755 });
|
|
118
|
+
return { success: true, message: 'Hook installed successfully!' };
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
return {
|
|
122
|
+
success: false,
|
|
123
|
+
message: `Failed to install hook: ${error instanceof Error ? error.message : error}`,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Uninstall the prepare-commit-msg hook
|
|
129
|
+
*/
|
|
130
|
+
static uninstall() {
|
|
131
|
+
try {
|
|
132
|
+
const hookPath = this.getHookPath();
|
|
133
|
+
if (!fs.existsSync(hookPath)) {
|
|
134
|
+
return { success: true, message: 'Hook is not installed.' };
|
|
135
|
+
}
|
|
136
|
+
const content = fs.readFileSync(hookPath, 'utf-8');
|
|
137
|
+
if (!content.includes('CommitGenie')) {
|
|
138
|
+
return {
|
|
139
|
+
success: false,
|
|
140
|
+
message: 'Hook exists but was not installed by CommitGenie. Not removing.',
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
fs.unlinkSync(hookPath);
|
|
144
|
+
// Restore backup if exists
|
|
145
|
+
const backupPath = `${hookPath}.backup`;
|
|
146
|
+
if (fs.existsSync(backupPath)) {
|
|
147
|
+
fs.renameSync(backupPath, hookPath);
|
|
148
|
+
return {
|
|
149
|
+
success: true,
|
|
150
|
+
message: 'Hook uninstalled and previous hook restored.',
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return { success: true, message: 'Hook uninstalled successfully!' };
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
return {
|
|
157
|
+
success: false,
|
|
158
|
+
message: `Failed to uninstall hook: ${error instanceof Error ? error.message : error}`,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
exports.HookService = HookService;
|
|
164
|
+
//# sourceMappingURL=hookService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hookService.js","sourceRoot":"","sources":["../../src/services/hookService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CommitStats } from '../types';
|
|
2
|
+
export declare class StatsService {
|
|
3
|
+
/**
|
|
4
|
+
* Get commit statistics for the repository
|
|
5
|
+
*/
|
|
6
|
+
static getCommitStats(commitCount?: number): CommitStats;
|
|
7
|
+
/**
|
|
8
|
+
* Get commits from git history
|
|
9
|
+
*/
|
|
10
|
+
private static getCommits;
|
|
11
|
+
/**
|
|
12
|
+
* Get recent activity for the last 7 days
|
|
13
|
+
*/
|
|
14
|
+
private static getRecentActivity;
|
|
15
|
+
/**
|
|
16
|
+
* Get empty stats object
|
|
17
|
+
*/
|
|
18
|
+
private static getEmptyStats;
|
|
19
|
+
/**
|
|
20
|
+
* Format stats for display
|
|
21
|
+
*/
|
|
22
|
+
static formatStats(stats: CommitStats): string;
|
|
23
|
+
/**
|
|
24
|
+
* Create a visual bar for charts
|
|
25
|
+
*/
|
|
26
|
+
private static createBar;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=statsService.d.ts.map
|