Skip to content

Commit aab74fa

Browse files
committed
fix: getCommitData parsing and error handling
1 parent c7d1adb commit aab74fa

File tree

2 files changed

+120
-13
lines changed

2 files changed

+120
-13
lines changed

src/proxy/processors/push-action/parsePush.ts

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,26 @@ const getCommitData = (contents: CommitContent[]) => {
7272
return lod
7373
.chain(contents)
7474
.filter({ type: 1 })
75-
.map((x) => {
75+
.map((x: CommitContent) => {
7676
console.log({ x });
7777

78-
const formattedContent = x.content.split('\n');
79-
console.log({ formattedContent });
78+
const allLines = x.content.split('\n');
79+
const trimmedLines = allLines.map((line) => line.trim());
80+
console.log({ trimmedLines });
8081

81-
const parts = formattedContent.filter((part) => part.length > 0);
82+
const parts = trimmedLines.filter((part) => part.length > 0);
8283
console.log({ parts });
8384

84-
if (!parts || parts.length < 5) {
85-
throw new Error('Invalid commit data');
85+
if (!parts || parts.length < 4) {
86+
throw new Error(
87+
`Invalid commit structure: Expected at least 4 non-empty lines (tree, author, committer, message), found ${parts.length}`
88+
);
89+
}
90+
91+
const indexOfMessages = trimmedLines.indexOf('');
92+
93+
if (indexOfMessages === -1) {
94+
throw new Error('Invalid commit data: Missing message separator');
8695
}
8796

8897
const tree = parts
@@ -111,12 +120,10 @@ const getCommitData = (contents: CommitContent[]) => {
111120
.trim();
112121
console.log({ committer });
113122

114-
const indexOfMessages = formattedContent.indexOf('');
115-
console.log({ indexOfMessages });
116-
117-
const message = formattedContent
118-
.slice(indexOfMessages + 1, formattedContent.length - 1)
119-
.join(' ');
123+
const message = trimmedLines
124+
.slice(indexOfMessages + 1)
125+
.join('\n')
126+
.trim();
120127
console.log({ message });
121128

122129
const commitTimestamp = committer?.split(' ').reverse()[1];
@@ -136,7 +143,15 @@ const getCommitData = (contents: CommitContent[]) => {
136143
});
137144

138145
if (!tree || !parent || !author || !committer || !commitTimestamp || !message || !authorEmail) {
139-
throw new Error('Invalid commit data');
146+
const missing = [];
147+
if (!tree) missing.push('tree');
148+
if (!parent) missing.push('parent');
149+
if (!author) missing.push('author');
150+
if (!committer) missing.push('committer');
151+
if (!commitTimestamp) missing.push('commitTimestamp');
152+
if (!message) missing.push('message');
153+
if (!authorEmail) missing.push('authorEmail');
154+
throw new Error(`Invalid commit data: Missing ${missing.join(', ')}`);
140155
}
141156

142157
return {
@@ -293,6 +308,7 @@ exec.displayName = 'parsePush.exec';
293308

294309
export {
295310
exec,
311+
getCommitData,
296312
getPackMeta,
297313
unpack
298314
};

test/testParsePush.test.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,4 +321,95 @@ describe('parsePackFile', () => {
321321
});
322322
});
323323

324+
325+
describe('getCommitData', () => {
326+
it('should return empty array if no type 1 contents', () => {
327+
const contents = [{ type: 2, content: 'blob' }, { type: 3, content: 'tree' }];
328+
expect(getCommitData(contents)).to.deep.equal([]);
329+
});
330+
331+
it('should parse a single valid commit object', () => {
332+
const commitContent = `tree 123\nparent 456\nauthor Au Thor <[email protected]> 111 +0000\ncommitter Com Itter <[email protected]> 222 +0100\n\nCommit message here`;
333+
const contents = [{ type: 1, content: commitContent }];
334+
const result = getCommitData(contents);
335+
336+
expect(result).to.be.an('array').with.lengthOf(1);
337+
expect(result[0]).to.deep.equal({
338+
tree: '123',
339+
parent: '456',
340+
author: 'Au Thor',
341+
committer: 'Com Itter',
342+
commitTimestamp: '222',
343+
message: 'Commit message here',
344+
authorEmail: '[email protected]',
345+
});
346+
});
347+
348+
it('should parse multiple valid commit objects', () => {
349+
const commit1 = `tree 111\nparent 000\nauthor A1 <[email protected]> 1678880001 +0000\ncommitter C1 <[email protected]> 1678880002 +0000\n\nMsg1`;
350+
const commit2 = `tree 222\nparent 111\nauthor A2 <[email protected]> 1678880003 +0100\ncommitter C2 <[email protected]> 1678880004 +0100\n\nMsg2`;
351+
const contents = [
352+
{ type: 1, content: commit1 },
353+
{ type: 3, content: 'tree data' }, // non-commit types must be ignored
354+
{ type: 1, content: commit2 },
355+
];
356+
357+
const result = getCommitData(contents);
358+
expect(result).to.be.an('array').with.lengthOf(2);
359+
360+
// Check first commit data
361+
expect(result[0].message).to.equal('Msg1');
362+
expect(result[0].parent).to.equal('000');
363+
expect(result[0].author).to.equal('A1');
364+
expect(result[0].committer).to.equal('C1');
365+
expect(result[0].authorEmail).to.equal('[email protected]');
366+
expect(result[0].commitTimestamp).to.equal('1678880002');
367+
368+
// Check second commit data
369+
expect(result[1].message).to.equal('Msg2');
370+
expect(result[1].parent).to.equal('111');
371+
expect(result[1].author).to.equal('A2');
372+
expect(result[1].committer).to.equal('C2');
373+
expect(result[1].authorEmail).to.equal('[email protected]');
374+
expect(result[1].commitTimestamp).to.equal('1678880004');
375+
});
376+
377+
it('should default parent to zero hash if not present', () => {
378+
const commitContent = `tree 123\nauthor Au Thor <[email protected]> 111 +0000\ncommitter Com Itter <[email protected]> 222 +0100\n\nCommit message here`;
379+
const contents = [{ type: 1, content: commitContent }];
380+
const result = getCommitData(contents);
381+
expect(result[0].parent).to.equal('0'.repeat(40));
382+
});
383+
384+
it('should handle commit messages with multiple lines', () => {
385+
const commitContent = `tree 123\nparent 456\nauthor A <[email protected]> 111 +0000 1\ncommitter C <[email protected]> 2\n\nLine one\nLine two\n\nLine four`;
386+
const contents = [{ type: 1, content: commitContent }];
387+
const result = getCommitData(contents);
388+
expect(result[0].message).to.equal('Line one\nLine two\n\nLine four');
389+
});
390+
391+
it('should throw error for invalid commit data (missing tree)', () => {
392+
const commitContent = `parent 456\nauthor A <[email protected]> 1\ncommitter C <[email protected]> 2\n\nMsg`;
393+
const contents = [{ type: 1, content: commitContent }];
394+
expect(() => getCommitData(contents)).to.throw('Invalid commit data');
395+
});
396+
397+
it('should throw error for invalid commit data (missing author)', () => {
398+
const commitContent = `tree 123\nparent 456\ncommitter C <[email protected]> 2\n\nMsg`;
399+
const contents = [{ type: 1, content: commitContent }];
400+
expect(() => getCommitData(contents)).to.throw('Invalid commit data');
401+
});
402+
403+
it('should throw error for invalid commit data (missing committer)', () => {
404+
const commitContent = `tree 123\nparent 456\nauthor A <[email protected]> 1\n\nMsg`;
405+
const contents = [{ type: 1, content: commitContent }];
406+
expect(() => getCommitData(contents)).to.throw('Invalid commit data');
407+
});
408+
409+
it('should throw error for invalid commit data (missing message separator)', () => {
410+
const commitContent = `tree 123\nparent 456\nauthor A <[email protected]> 1\ncommitter C <[email protected]> 2`; // No empty line
411+
const contents = [{ type: 1, content: commitContent }];
412+
expect(() => getCommitData(contents)).to.throw('Invalid commit data');
413+
});
414+
});
324415
});

0 commit comments

Comments
 (0)