Skip to content

Commit

Permalink
feat: support binary file diff (fixes #17)
Browse files Browse the repository at this point in the history
  • Loading branch information
yeonjuan committed Jul 31, 2023
1 parent 468b932 commit 09bab17
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/__fixtures__/changed-binary-file
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
diff --git a/file1 b/file1
index 21be030..9443748 100644
Binary files a/file1 and b/file1 differ
4 changes: 4 additions & 0 deletions src/__fixtures__/deleted-binary-file
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
diff --git a/file1 b/file1
deleted file mode 100644
index 21be030..0000000
Binary files a/file1 and /dev/null differ
4 changes: 4 additions & 0 deletions src/__fixtures__/new-binary-file
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
diff --git a/file1 b/file1
new file mode 100644
index 0000000..21be030
Binary files /dev/null and b/file1 differ
20 changes: 20 additions & 0 deletions src/__tests__/__snapshots__/changed-binary-file.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`changed binary file parse \`changed-binary-file\` 1`] = `
{
"files": [
{
"chunks": [
{
"pathAfter": "file1",
"pathBefore": "file1",
"type": "BinaryFilesChunk",
},
],
"path": "file1",
"type": "ChangedFile",
},
],
"type": "GitDiff",
}
`;
20 changes: 20 additions & 0 deletions src/__tests__/__snapshots__/deleted-binary-file.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`deleted binary file parse \`deleted-binary-file\` 1`] = `
{
"files": [
{
"chunks": [
{
"pathAfter": "/dev/null",
"pathBefore": "file1",
"type": "BinaryFilesChunk",
},
],
"path": "file1",
"type": "DeletedFile",
},
],
"type": "GitDiff",
}
`;
20 changes: 20 additions & 0 deletions src/__tests__/__snapshots__/new-binary-file.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`new-binary-file parse \`new-binary-file\` 1`] = `
{
"files": [
{
"chunks": [
{
"pathAfter": "file1",
"pathBefore": "/dev/null",
"type": "BinaryFilesChunk",
},
],
"path": "file1",
"type": "AddedFile",
},
],
"type": "GitDiff",
}
`;
10 changes: 10 additions & 0 deletions src/__tests__/changed-binary-file.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { getFixture } from './test-utils';
import parseGitDiff from '../parse-git-diff';

describe('changed binary file', () => {
const fixture = getFixture('changed-binary-file');

it('parse `changed-binary-file`', () => {
expect(parseGitDiff(fixture)).toMatchSnapshot();
});
});
10 changes: 10 additions & 0 deletions src/__tests__/deleted-binary-file.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { getFixture } from './test-utils';
import parseGitDiff from '../parse-git-diff';

describe('deleted binary file', () => {
const fixture = getFixture('deleted-binary-file');

it('parse `deleted-binary-file`', () => {
expect(parseGitDiff(fixture)).toMatchSnapshot();
});
});
10 changes: 10 additions & 0 deletions src/__tests__/new-binary-file.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { getFixture } from './test-utils';
import parseGitDiff from '../parse-git-diff';

describe('new-binary-file', () => {
const fixture = getFixture('new-binary-file');

it('parse `new-binary-file`', () => {
expect(parseGitDiff(fixture)).toMatchSnapshot();
});
});
51 changes: 51 additions & 0 deletions src/parse-git-diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,28 @@ function parseFileChange(ctx: Context): AnyFileChange | undefined {
chunks,
path: changeMarkers.deleted,
};
} else if (
isDeleted &&
chunks.length &&
chunks[0].type === 'BinaryFilesChunk'
) {
return {
type: FileType.Deleted,
chunks,
path: chunks[0].pathBefore,
};
} else if (isNew && changeMarkers) {
return {
type: FileType.Added,
chunks,
path: changeMarkers.added,
};
} else if (isNew && chunks.length && chunks[0].type === 'BinaryFilesChunk') {
return {
type: FileType.Added,
chunks,
path: chunks[0].pathAfter,
};
} else if (isRename) {
return {
type: FileType.Renamed,
Expand All @@ -93,7 +109,18 @@ function parseFileChange(ctx: Context): AnyFileChange | undefined {
chunks,
path: changeMarkers.added,
};
} else if (
chunks.length &&
chunks[0].type === 'BinaryFilesChunk' &&
chunks[0].pathAfter === chunks[0].pathBefore
) {
return {
type: FileType.Changed,
chunks,
path: chunks[0].pathAfter,
};
}

return;
}

Expand Down Expand Up @@ -148,6 +175,16 @@ function parseChunk(context: Context): AnyChunk | undefined {
type: 'CombinedChunk',
changes,
};
} else if (
chunkHeader.type === 'BinaryFilesDiffer' &&
chunkHeader.fileA &&
chunkHeader.fileB
) {
return {
type: 'BinaryFilesChunk',
pathBefore: chunkHeader.fileA,
pathAfter: chunkHeader.fileB,
};
}
}

Expand Down Expand Up @@ -184,6 +221,19 @@ function parseChunkHeader(ctx: Context) {
);

if (!combinedChunkExec) {
const binaryChunkExec = /^Binary\sfiles\s(.*)\sand\s(.*)\sdiffer$/.exec(
line
);
if (binaryChunkExec) {
const [all, fileA, fileB] = binaryChunkExec;
ctx.nextLine();
return {
type: 'BinaryFilesDiffer',
fileA: fileA.replace('a/', ''),
fileB: fileB.replace('b/', ''),
} as const;
}

return null;
}

Expand All @@ -206,6 +256,7 @@ function parseChunkHeader(ctx: Context) {
toFileRange: getRange(addStart, addLines),
} as const;
}

const [all, delStart, delLines, addStart, addLines, context] =
normalChunkExec;
ctx.nextLine();
Expand Down
7 changes: 6 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ export interface CombinedChunk extends Base<'CombinedChunk'> {
context: string | undefined;
}

export type AnyChunk = Chunk | CombinedChunk;
export interface BinaryFilesChunk extends Base<'BinaryFilesChunk'> {
pathBefore: string;
pathAfter: string;
}

export type AnyChunk = Chunk | CombinedChunk | BinaryFilesChunk;

export interface ChangedFile extends Base<typeof FileType.Changed> {
path: string;
Expand Down

0 comments on commit 09bab17

Please sign in to comment.