diff --git a/src/__fixtures__/added-empty-file b/src/__fixtures__/added-empty-file new file mode 100644 index 0000000..b8e4b8f --- /dev/null +++ b/src/__fixtures__/added-empty-file @@ -0,0 +1,3 @@ +diff --git a/src/empty b/src/empty +new file mode 100644 +index 0000000..e69de29 \ No newline at end of file diff --git a/src/__fixtures__/deleted-empty-file b/src/__fixtures__/deleted-empty-file new file mode 100644 index 0000000..94c6d26 --- /dev/null +++ b/src/__fixtures__/deleted-empty-file @@ -0,0 +1,3 @@ +diff --git a/src/empty b/src/empty +deleted file mode 100644 +index e69de29..0000000 \ No newline at end of file diff --git a/src/__fixtures__/renamed-empty b/src/__fixtures__/renamed-empty new file mode 100644 index 0000000..8fee8b8 --- /dev/null +++ b/src/__fixtures__/renamed-empty @@ -0,0 +1,4 @@ +diff --git a/src/empty b/src/renamed-empty +similarity index 100% +rename from src/empty +rename to src/renamed-empty \ No newline at end of file diff --git a/src/__tests__/__snapshots__/added-empty-file.test.ts.snap b/src/__tests__/__snapshots__/added-empty-file.test.ts.snap new file mode 100644 index 0000000..44f1615 --- /dev/null +++ b/src/__tests__/__snapshots__/added-empty-file.test.ts.snap @@ -0,0 +1,14 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`added-empty-file parse \`added-empty-file\` 1`] = ` +{ + "files": [ + { + "chunks": [], + "path": "src/empty", + "type": "AddedFile", + }, + ], + "type": "GitDiff", +} +`; diff --git a/src/__tests__/__snapshots__/deleted-empty-file.test.ts.snap b/src/__tests__/__snapshots__/deleted-empty-file.test.ts.snap new file mode 100644 index 0000000..59b07a9 --- /dev/null +++ b/src/__tests__/__snapshots__/deleted-empty-file.test.ts.snap @@ -0,0 +1,14 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`deleted-empty-file parse \`deleted-empty-file\` 1`] = ` +{ + "files": [ + { + "chunks": [], + "path": "src/empty", + "type": "DeletedFile", + }, + ], + "type": "GitDiff", +} +`; diff --git a/src/__tests__/__snapshots__/renamed-empty.test.ts.snap b/src/__tests__/__snapshots__/renamed-empty.test.ts.snap new file mode 100644 index 0000000..3a32eef --- /dev/null +++ b/src/__tests__/__snapshots__/renamed-empty.test.ts.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renamed-empty parse \`renamed-empty\` 1`] = ` +{ + "files": [ + { + "chunks": [], + "pathAfter": "src/renamed-empty", + "pathBefore": "src/empty", + "type": "RenamedFile", + }, + ], + "type": "GitDiff", +} +`; diff --git a/src/__tests__/added-empty-file.test.ts b/src/__tests__/added-empty-file.test.ts new file mode 100644 index 0000000..a4d3dd0 --- /dev/null +++ b/src/__tests__/added-empty-file.test.ts @@ -0,0 +1,10 @@ +import { getFixture } from './test-utils'; +import parseGitDiff from '../parse-git-diff'; + +describe('added-empty-file', () => { + const fixture = getFixture('added-empty-file'); + + it('parse `added-empty-file`', () => { + expect(parseGitDiff(fixture)).toMatchSnapshot(); + }); +}); diff --git a/src/__tests__/deleted-empty-file.test.ts b/src/__tests__/deleted-empty-file.test.ts new file mode 100644 index 0000000..d313986 --- /dev/null +++ b/src/__tests__/deleted-empty-file.test.ts @@ -0,0 +1,10 @@ +import { getFixture } from './test-utils'; +import parseGitDiff from '../parse-git-diff'; + +describe('deleted-empty-file', () => { + const fixture = getFixture('deleted-empty-file'); + + it('parse `deleted-empty-file`', () => { + expect(parseGitDiff(fixture)).toMatchSnapshot(); + }); +}); diff --git a/src/__tests__/renamed-empty.test.ts b/src/__tests__/renamed-empty.test.ts new file mode 100644 index 0000000..9700b3a --- /dev/null +++ b/src/__tests__/renamed-empty.test.ts @@ -0,0 +1,10 @@ +import { getFixture } from './test-utils'; +import parseGitDiff from '../parse-git-diff'; + +describe('renamed-empty', () => { + const fixture = getFixture('renamed-empty'); + + it('parse `renamed-empty`', () => { + expect(parseGitDiff(fixture)).toMatchSnapshot(); + }); +}); diff --git a/src/parse-git-diff.ts b/src/parse-git-diff.ts index 1075956..10426db 100644 --- a/src/parse-git-diff.ts +++ b/src/parse-git-diff.ts @@ -46,7 +46,7 @@ function parseFileChange(ctx: Context): AnyFileChange | undefined { if (!isComparisonInputLine(ctx.getCurLine())) { return; } - ctx.nextLine(); + const comparisonLineParsed = parseComparisonInputLine(ctx); let isDeleted = false; let isNew = false; @@ -55,11 +55,18 @@ function parseFileChange(ctx: Context): AnyFileChange | undefined { let pathAfter = ''; while (!ctx.isEof()) { const extHeader = parseExtendedHeader(ctx); + if (!extHeader) { break; } - if (extHeader.type === ExtendedHeader.Deleted) isDeleted = true; - if (extHeader.type === ExtendedHeader.NewFile) isNew = true; + if (extHeader.type === ExtendedHeader.Deleted) { + isDeleted = true; + pathBefore = comparisonLineParsed?.from || ''; + } + if (extHeader.type === ExtendedHeader.NewFile) { + isNew = true; + pathAfter = comparisonLineParsed?.to || ''; + } if (extHeader.type === ExtendedHeader.RenameFrom) { isRename = true; pathBefore = extHeader.path as string; @@ -73,33 +80,30 @@ function parseFileChange(ctx: Context): AnyFileChange | undefined { const changeMarkers = parseChangeMarkers(ctx); const chunks = parseChunks(ctx); - if (isDeleted && changeMarkers) { + if (isDeleted && chunks.length && chunks[0].type === 'BinaryFilesChunk') { return { type: FileType.Deleted, chunks, - path: changeMarkers.deleted, + path: chunks[0].pathBefore, }; - } else if ( - isDeleted && - chunks.length && - chunks[0].type === 'BinaryFilesChunk' - ) { + } + if (isDeleted) { return { type: FileType.Deleted, chunks, - path: chunks[0].pathBefore, + path: changeMarkers?.deleted || pathBefore, }; - } else if (isNew && changeMarkers) { + } else if (isNew && chunks.length && chunks[0].type === 'BinaryFilesChunk') { return { type: FileType.Added, chunks, - path: changeMarkers.added, + path: chunks[0].pathAfter, }; - } else if (isNew && chunks.length && chunks[0].type === 'BinaryFilesChunk') { + } else if (isNew) { return { type: FileType.Added, chunks, - path: chunks[0].pathAfter, + path: changeMarkers?.added || pathAfter, }; } else if (isRename) { return { @@ -133,6 +137,20 @@ function isComparisonInputLine(line: string): boolean { return line.indexOf('diff') === 0; } +function parseComparisonInputLine( + ctx: Context +): { from: string; to: string } | null { + const line = ctx.getCurLine(); + const splitted = line.split(' ').reverse(); + const to = splitted.find((p) => p.startsWith('b/'))?.replace('b/', ''); + const from = splitted.find((p) => p.startsWith('a/'))?.replace('a/', ''); + ctx.nextLine(); + if (to && from) { + return { to, from }; + } + return null; +} + function parseChunks(context: Context): AnyChunk[] { const chunks: AnyChunk[] = [];