Skip to content

Commit 4f39a03

Browse files
authored
feat: add noPrefix options (#21)
1 parent f20636c commit 4f39a03

File tree

6 files changed

+94
-7
lines changed

6 files changed

+94
-7
lines changed

README.md

+14
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ console.log(result);
5252
// }
5353
```
5454

55+
### Options
56+
57+
#### `noPrefix` (boolean)
58+
59+
Specifies whether the git diff command is used with the `--no-prefix` option. (default: `false`)
60+
61+
```ts
62+
// git diff HEAD~3 --no-prefix
63+
64+
const result = parseGitDiff(DIFF, {
65+
noPrefix: true,
66+
});
67+
```
68+
5569
## Examples
5670

5771
<details>

src/__tests__/options.test.ts

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import parseGitDiff from '../parse-git-diff';
2+
import { ChangedFile, RenamedFile } from '../types';
3+
4+
const getDiffFixture = ({
5+
srcPrefix = 'a/',
6+
dstPrefix = 'b/',
7+
}) => `diff --git ${srcPrefix}b/bbb.md ${dstPrefix}b/bbb.md
8+
index 0e05564..aa39060 100644
9+
--- ${srcPrefix}b/bbb.md
10+
+++ ${dstPrefix}b/bbb.md
11+
@@ -1,2 +1 @@
12+
newfile
13+
-newline
14+
+newline
15+
\ No newline at end of file`;
16+
17+
describe('options', () => {
18+
it('noPrefix=true', () => {
19+
const output = parseGitDiff(
20+
getDiffFixture({ srcPrefix: '', dstPrefix: '' }),
21+
{
22+
noPrefix: true,
23+
}
24+
);
25+
26+
expect((output.files[0] as ChangedFile).path).toBe('b/bbb.md');
27+
});
28+
29+
it('noPrefix=false', () => {
30+
const output = parseGitDiff(
31+
getDiffFixture({ srcPrefix: 'a/', dstPrefix: 'b/' }),
32+
{
33+
noPrefix: false,
34+
}
35+
);
36+
37+
expect((output.files[0] as ChangedFile).path).toBe('b/bbb.md');
38+
});
39+
});

src/context.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1+
import { FilledGitDiffOptions, GitDiffOptions } from './types';
2+
13
export default class Context {
24
private line: number = 1;
35
private lines: string[] = [];
4-
public constructor(diff: string) {
6+
public options: FilledGitDiffOptions = {
7+
noPrefix: false,
8+
};
9+
public constructor(diff: string, options?: GitDiffOptions) {
510
this.lines = diff.split('\n');
11+
12+
this.options.noPrefix = !!options?.noPrefix;
613
}
714

815
public getCurLine(): string {

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ export type {
1717
RenamedFile,
1818
AnyFileChange,
1919
GitDiff,
20+
GitDiffOptions,
2021
} from './types.js';

src/parse-git-diff.ts

+26-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import type {
77
ChunkRange,
88
CombinedChunk,
99
AnyChunk,
10+
FilledGitDiffOptions,
11+
GitDiffOptions,
1012
} from './types.js';
1113
import {
1214
ExtendedHeader,
@@ -15,8 +17,11 @@ import {
1517
LineType,
1618
} from './constants.js';
1719

18-
export default function parseGitDiff(diff: string): GitDiff {
19-
const ctx = new Context(diff);
20+
export default function parseGitDiff(
21+
diff: string,
22+
options?: GitDiffOptions
23+
): GitDiff {
24+
const ctx = new Context(diff, options);
2025
const files = parseFileChanges(ctx);
2126

2227
return {
@@ -229,8 +234,8 @@ function parseChunkHeader(ctx: Context) {
229234
ctx.nextLine();
230235
return {
231236
type: 'BinaryFiles',
232-
fileA: fileA.replace('a/', ''),
233-
fileB: fileB.replace('b/', ''),
237+
fileA: getFilePath(ctx, fileA, 'src'),
238+
fileB: getFilePath(ctx, fileB, 'dst'),
234239
} as const;
235240
}
236241

@@ -280,8 +285,15 @@ function parseChangeMarkers(context: Context): {
280285
deleted: string;
281286
added: string;
282287
} | null {
283-
const deleted = parseMarker(context, '--- ')?.replace('a/', '');
284-
const added = parseMarker(context, '+++ ')?.replace('b/', '');
288+
const deleterMarker = parseMarker(context, '--- ');
289+
const deleted = deleterMarker
290+
? getFilePath(context, deleterMarker, 'src')
291+
: deleterMarker;
292+
293+
const addedMarker = parseMarker(context, '+++ ');
294+
const added = addedMarker
295+
? getFilePath(context, addedMarker, 'dst')
296+
: addedMarker;
285297
return added && deleted ? { added, deleted } : null;
286298
}
287299

@@ -364,3 +376,11 @@ function parseChanges(
364376
function getLineType(line: string): LineType | null {
365377
return CHAR_TYPE_MAP[line[0]] || null;
366378
}
379+
380+
function getFilePath(ctx: Context, input: string, type: 'src' | 'dst') {
381+
if (ctx.options.noPrefix) {
382+
return input;
383+
}
384+
if (type === 'src') return input.replace(/^a\//, '');
385+
if (type === 'dst') return input.replace(/^b\//, '');
386+
}

src/types.ts

+6
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,9 @@ export type AnyFileChange = ChangedFile | AddedFile | DeletedFile | RenamedFile;
8484
export interface GitDiff extends Base<'GitDiff'> {
8585
files: AnyFileChange[];
8686
}
87+
88+
export interface FilledGitDiffOptions {
89+
noPrefix: boolean;
90+
}
91+
92+
export type GitDiffOptions = Partial<FilledGitDiffOptions>;

0 commit comments

Comments
 (0)