critique 0.1.127 → 0.1.129
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/dist/diff-utils.d.ts.map +1 -1
- package/dist/diff-utils.js +35 -4
- package/dist/diff-utils.test.js +64 -1
- package/dist/directory-tree.d.ts.map +1 -1
- package/dist/directory-tree.js +13 -0
- package/dist/directory-tree.test.js +37 -15
- package/dist/stdin-pager.test.js +40 -0
- package/package.json +1 -1
- package/src/diff-utils.test.ts +77 -0
- package/src/diff-utils.ts +36 -5
- package/src/directory-tree.test.tsx +40 -15
- package/src/directory-tree.ts +14 -0
- package/src/stdin-pager.test.ts +40 -0
package/dist/diff-utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff-utils.d.ts","sourceRoot":"","sources":["../src/diff-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"diff-utils.d.ts","sourceRoot":"","sources":["../src/diff-utils.ts"],"names":[],"mappings":"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"}
|
package/dist/diff-utils.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Builds git commands, parses diff files, detects filetypes for syntax highlighting,
|
|
3
3
|
// and provides helpers for unified/split view mode selection.
|
|
4
4
|
import { execSync } from "child_process";
|
|
5
|
+
import { buildDirectoryTree } from "./directory-tree.js";
|
|
5
6
|
/**
|
|
6
7
|
* Strip submodule status lines from git diff output.
|
|
7
8
|
* git diff --submodule=diff adds various status lines that the diff parser doesn't understand:
|
|
@@ -414,11 +415,41 @@ export function processFiles(files, formatPatch) {
|
|
|
414
415
|
const totalLines = file.hunks.reduce((sum, hunk) => sum + hunk.lines.length, 0);
|
|
415
416
|
return totalLines <= 6000;
|
|
416
417
|
});
|
|
417
|
-
const
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
418
|
+
const treeFiles = filteredFiles.map((file, index) => {
|
|
419
|
+
const { additions, deletions } = countChanges(file.hunks);
|
|
420
|
+
return {
|
|
421
|
+
path: getFileName(file),
|
|
422
|
+
status: getFileStatus(file),
|
|
423
|
+
additions,
|
|
424
|
+
deletions,
|
|
425
|
+
fileIndex: index,
|
|
426
|
+
};
|
|
421
427
|
});
|
|
428
|
+
const treeFileOrder = buildDirectoryTree(treeFiles)
|
|
429
|
+
.filter((node) => node.isFile && node.fileIndex !== undefined)
|
|
430
|
+
.map((node) => node.fileIndex);
|
|
431
|
+
const seenIndexes = new Set();
|
|
432
|
+
const sortedFiles = [];
|
|
433
|
+
for (const index of treeFileOrder) {
|
|
434
|
+
if (seenIndexes.has(index))
|
|
435
|
+
continue;
|
|
436
|
+
const file = filteredFiles[index];
|
|
437
|
+
if (!file)
|
|
438
|
+
continue;
|
|
439
|
+
seenIndexes.add(index);
|
|
440
|
+
sortedFiles.push(file);
|
|
441
|
+
}
|
|
442
|
+
// Defensive fallback: keep any unmatched files in original order.
|
|
443
|
+
// This should be rare, but avoids dropping files if tree metadata and
|
|
444
|
+
// parsed file list ever diverge.
|
|
445
|
+
for (let index = 0; index < filteredFiles.length; index++) {
|
|
446
|
+
if (seenIndexes.has(index))
|
|
447
|
+
continue;
|
|
448
|
+
const file = filteredFiles[index];
|
|
449
|
+
if (!file)
|
|
450
|
+
continue;
|
|
451
|
+
sortedFiles.push(file);
|
|
452
|
+
}
|
|
422
453
|
// Add rawDiff for each file
|
|
423
454
|
return sortedFiles.map((file) => ({
|
|
424
455
|
...file,
|
package/dist/diff-utils.test.js
CHANGED
|
@@ -4,7 +4,70 @@
|
|
|
4
4
|
// extracts rename metadata for all rename/copy sections.
|
|
5
5
|
import { describe, expect, it } from "bun:test";
|
|
6
6
|
import { parsePatch, formatPatch } from "diff";
|
|
7
|
-
import { preprocessDiff, parseGitDiffFiles, getFileStatus, getFileName, getOldFileName, buildGitCommand, buildSubmoduleDiffCommand, filterParsedFilesByPatterns, getFilterPatterns, matchesFileFilters, detectFiletype, } from "./diff-utils.js";
|
|
7
|
+
import { preprocessDiff, parseGitDiffFiles, processFiles, getFileStatus, getFileName, getOldFileName, buildGitCommand, buildSubmoduleDiffCommand, filterParsedFilesByPatterns, getFilterPatterns, matchesFileFilters, detectFiletype, } from "./diff-utils.js";
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// processFiles ordering
|
|
10
|
+
// ============================================================================
|
|
11
|
+
describe("processFiles ordering", () => {
|
|
12
|
+
it("should order output files to match directory tree traversal", () => {
|
|
13
|
+
const files = [
|
|
14
|
+
{
|
|
15
|
+
oldFileName: "src/components/button.tsx",
|
|
16
|
+
newFileName: "src/components/button.tsx",
|
|
17
|
+
hunks: [{ lines: Array.from({ length: 90 }, () => "+line") }],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
oldFileName: "src/index.ts",
|
|
21
|
+
newFileName: "src/index.ts",
|
|
22
|
+
hunks: [{ lines: ["+line"] }],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
oldFileName: "README.md",
|
|
26
|
+
newFileName: "README.md",
|
|
27
|
+
hunks: [{ lines: ["+line", "+line", "+line"] }],
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
const processed = processFiles(files, (file) => `diff --git ${file.oldFileName} ${file.newFileName}`);
|
|
31
|
+
expect(processed.map((file) => getFileName(file))).toEqual([
|
|
32
|
+
"README.md",
|
|
33
|
+
"src/components/button.tsx",
|
|
34
|
+
"src/index.ts",
|
|
35
|
+
]);
|
|
36
|
+
});
|
|
37
|
+
it("should keep tree order with renamed, added, and deleted files", () => {
|
|
38
|
+
const files = [
|
|
39
|
+
{
|
|
40
|
+
oldFileName: "src/alpha.ts",
|
|
41
|
+
newFileName: "src/alpha.ts",
|
|
42
|
+
hunks: [{ lines: Array.from({ length: 30 }, () => "+line") }],
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
oldFileName: "docs/old-name.md",
|
|
46
|
+
newFileName: "docs/new-name.md",
|
|
47
|
+
renameFrom: "docs/old-name.md",
|
|
48
|
+
renameTo: "docs/new-name.md",
|
|
49
|
+
hunks: [{ lines: ["+line"] }],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
oldFileName: "/dev/null",
|
|
53
|
+
newFileName: "docs/guide.md",
|
|
54
|
+
hunks: [{ lines: ["+line", "+line"] }],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
oldFileName: "src/remove.ts",
|
|
58
|
+
newFileName: "/dev/null",
|
|
59
|
+
hunks: [{ lines: ["-line"] }],
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
const processed = processFiles(files, (file) => `diff --git ${file.oldFileName} ${file.newFileName}`);
|
|
63
|
+
expect(processed.map((file) => getFileName(file))).toEqual([
|
|
64
|
+
"docs/guide.md",
|
|
65
|
+
"docs/new-name.md",
|
|
66
|
+
"src/alpha.ts",
|
|
67
|
+
"src/remove.ts",
|
|
68
|
+
]);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
8
71
|
// ============================================================================
|
|
9
72
|
// preprocessDiff
|
|
10
73
|
// ============================================================================
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directory-tree.d.ts","sourceRoot":"","sources":["../src/directory-tree.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAA;AAErE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,UAAU,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAA;IACnB,yDAAyD;IACzD,MAAM,EAAE,OAAO,CAAA;IACf,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAA;IACjB,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAA;CACf;AAYD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"directory-tree.d.ts","sourceRoot":"","sources":["../src/directory-tree.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAA;AAErE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,UAAU,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAA;IACnB,yDAAyD;IACzD,MAAM,EAAE,OAAO,CAAA;IACf,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAA;IACjB,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAA;CACf;AAYD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,QAAQ,EAAE,CAQpE"}
|
package/dist/directory-tree.js
CHANGED
|
@@ -11,6 +11,7 @@ export function buildDirectoryTree(files) {
|
|
|
11
11
|
return [];
|
|
12
12
|
}
|
|
13
13
|
const tree = buildInternalTree(files);
|
|
14
|
+
sortInternalTree(tree);
|
|
14
15
|
return flattenTree(tree);
|
|
15
16
|
}
|
|
16
17
|
/**
|
|
@@ -55,6 +56,18 @@ function getName(node) {
|
|
|
55
56
|
const parts = node.path.split("/");
|
|
56
57
|
return parts[parts.length - 1] || node.path;
|
|
57
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Sort tree nodes by name at every level so file ordering is deterministic
|
|
61
|
+
* and independent from incoming git diff section order.
|
|
62
|
+
*/
|
|
63
|
+
function sortInternalTree(nodes) {
|
|
64
|
+
nodes.sort((a, b) => getName(a).toLowerCase().localeCompare(getName(b).toLowerCase()));
|
|
65
|
+
for (const node of nodes) {
|
|
66
|
+
if (node.children.length > 0) {
|
|
67
|
+
sortInternalTree(node.children);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
58
71
|
/**
|
|
59
72
|
* Collapse directories that only contain a single subdirectory (no files)
|
|
60
73
|
*/
|
|
@@ -44,6 +44,28 @@ describe("buildDirectoryTree", () => {
|
|
|
44
44
|
expect(result[1].displayPath).toBe("Button.tsx");
|
|
45
45
|
expect(result[1].isFile).toBe(true);
|
|
46
46
|
});
|
|
47
|
+
it("should sort nodes alphabetically regardless of input order", () => {
|
|
48
|
+
const files = [
|
|
49
|
+
{ path: "website/src/index.ts", status: "modified", additions: 1, deletions: 0 },
|
|
50
|
+
{ path: "db/schema.prisma", status: "modified", additions: 1, deletions: 0 },
|
|
51
|
+
{ path: "discord/src/utils.ts", status: "modified", additions: 1, deletions: 0 },
|
|
52
|
+
{ path: "discord/src/cli.ts", status: "modified", additions: 1, deletions: 0 },
|
|
53
|
+
{ path: "gateway-proxy/src/main.rs", status: "modified", additions: 1, deletions: 0 },
|
|
54
|
+
];
|
|
55
|
+
const result = buildDirectoryTree(files);
|
|
56
|
+
const rendered = result.map((node) => `${node.prefix}${node.connector}${node.displayPath}`);
|
|
57
|
+
expect(rendered).toEqual([
|
|
58
|
+
"├── db",
|
|
59
|
+
"│ └── schema.prisma",
|
|
60
|
+
"├── discord/src",
|
|
61
|
+
"│ ├── cli.ts",
|
|
62
|
+
"│ └── utils.ts",
|
|
63
|
+
"├── gateway-proxy/src",
|
|
64
|
+
"│ └── main.rs",
|
|
65
|
+
"└── website/src",
|
|
66
|
+
" └── index.ts",
|
|
67
|
+
]);
|
|
68
|
+
});
|
|
47
69
|
});
|
|
48
70
|
describe("TreeRenderer visual tests", () => {
|
|
49
71
|
let testSetup;
|
|
@@ -166,10 +188,10 @@ describe("TreeRenderer visual tests", () => {
|
|
|
166
188
|
expect(frame).toMatchInlineSnapshot(`
|
|
167
189
|
"├── package.json (+2,-1)
|
|
168
190
|
├── src
|
|
169
|
-
│ ├── index.ts (+10,-5)
|
|
170
191
|
│ ├── components
|
|
171
192
|
│ │ ├── Button.tsx (+50,-0)
|
|
172
193
|
│ │ └── Input.tsx (+15,-8)
|
|
194
|
+
│ ├── index.ts (+10,-5)
|
|
173
195
|
│ └── utils
|
|
174
196
|
│ └── helpers.ts (+0,-30)
|
|
175
197
|
└── tests
|
|
@@ -197,8 +219,8 @@ describe("TreeRenderer visual tests", () => {
|
|
|
197
219
|
const frame = testSetup.captureCharFrame();
|
|
198
220
|
expect(frame).toMatchInlineSnapshot(`
|
|
199
221
|
"└── packages/core/src/lib/utils
|
|
200
|
-
├──
|
|
201
|
-
└──
|
|
222
|
+
├── format.ts (+20,-0)
|
|
223
|
+
└── helpers.ts (+5,-3)
|
|
202
224
|
|
|
203
225
|
|
|
204
226
|
|
|
@@ -222,14 +244,14 @@ describe("TreeRenderer visual tests", () => {
|
|
|
222
244
|
await testSetup.renderOnce();
|
|
223
245
|
const frame = testSetup.captureCharFrame();
|
|
224
246
|
expect(frame).toMatchInlineSnapshot(`
|
|
225
|
-
"├──
|
|
226
|
-
│
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
247
|
+
"├── lib
|
|
248
|
+
│ └── utils.ts (+15,-0)
|
|
249
|
+
└── src
|
|
250
|
+
├── api
|
|
251
|
+
│ ├── handlers.ts (+30,-0)
|
|
252
|
+
│ └── routes.ts (+10,-5)
|
|
253
|
+
└── db
|
|
254
|
+
└── models.ts (+8,-2)
|
|
233
255
|
|
|
234
256
|
|
|
235
257
|
|
|
@@ -256,10 +278,10 @@ describe("DirectoryTreeView component", () => {
|
|
|
256
278
|
await testSetup.renderOnce();
|
|
257
279
|
const frame = testSetup.captureCharFrame();
|
|
258
280
|
expect(frame).toMatchInlineSnapshot(`
|
|
259
|
-
" ├──
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
281
|
+
" ├── README.md (-15)
|
|
282
|
+
└── src
|
|
283
|
+
├── index.ts (+5,-2)
|
|
284
|
+
└── utils.ts (+30)
|
|
263
285
|
|
|
264
286
|
|
|
265
287
|
|
package/dist/stdin-pager.test.js
CHANGED
|
@@ -176,6 +176,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
176
176
|
const trimmed = await session.text({ trimEnd: true });
|
|
177
177
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
178
178
|
"
|
|
179
|
+
└── b/src
|
|
180
|
+
└── hello.ts (+1,-1)
|
|
181
|
+
|
|
182
|
+
|
|
179
183
|
a/src/hello.ts → b/src/hello.ts +1-1
|
|
180
184
|
|
|
181
185
|
1 const greeting = 'hello'
|
|
@@ -209,6 +213,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
209
213
|
const trimmed = await session.text({ trimEnd: true, immediate: true });
|
|
210
214
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
211
215
|
"
|
|
216
|
+
└── b
|
|
217
|
+
└── readme.md ()
|
|
218
|
+
|
|
219
|
+
|
|
212
220
|
a/readme.md → b/readme.md +0-0
|
|
213
221
|
|
|
214
222
|
1 # My Project
|
|
@@ -224,6 +232,11 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
224
232
|
const trimmed = await session.text({ trimEnd: true });
|
|
225
233
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
226
234
|
"
|
|
235
|
+
└── b/src
|
|
236
|
+
├── logger.ts (+5)
|
|
237
|
+
└── index.ts (+2)
|
|
238
|
+
|
|
239
|
+
|
|
227
240
|
b/src/logger.ts +5-0
|
|
228
241
|
|
|
229
242
|
1 + export class Logger {
|
|
@@ -258,6 +271,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
258
271
|
const trimmed = await session.text({ trimEnd: true });
|
|
259
272
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
260
273
|
"
|
|
274
|
+
└── a/src
|
|
275
|
+
└── deprecated.ts (-4)
|
|
276
|
+
|
|
277
|
+
|
|
261
278
|
a/src/deprecated.ts +0-4
|
|
262
279
|
|
|
263
280
|
1 - // This module is no longer needed
|
|
@@ -276,6 +293,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
276
293
|
const trimmed = await session.text({ trimEnd: true });
|
|
277
294
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
278
295
|
"
|
|
296
|
+
└── b/src
|
|
297
|
+
└── utils.ts (+7)
|
|
298
|
+
|
|
299
|
+
|
|
279
300
|
b/src/utils.ts +7-0
|
|
280
301
|
|
|
281
302
|
1 + export function clamp(value: number, min: number, max: number): number {
|
|
@@ -298,6 +319,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
298
319
|
const trimmed = await session.text({ trimEnd: true });
|
|
299
320
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
300
321
|
"
|
|
322
|
+
└── b
|
|
323
|
+
└── config.json (+6,-4)
|
|
324
|
+
|
|
325
|
+
|
|
301
326
|
a/config.json → b/config.json +6-4
|
|
302
327
|
|
|
303
328
|
1 {
|
|
@@ -328,6 +353,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
328
353
|
const trimmed = await session.text({ trimEnd: true });
|
|
329
354
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
330
355
|
"
|
|
356
|
+
└── src
|
|
357
|
+
└── new-name.ts (+1,-1)
|
|
358
|
+
|
|
359
|
+
|
|
331
360
|
src/old-name.ts → src/new-name.ts +1-1
|
|
332
361
|
|
|
333
362
|
1 - export const name = 'old'
|
|
@@ -349,6 +378,9 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
349
378
|
const trimmed = await session.text({ trimEnd: true, immediate: true });
|
|
350
379
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
351
380
|
"
|
|
381
|
+
└── unknown ()
|
|
382
|
+
|
|
383
|
+
|
|
352
384
|
unknown +0-0"
|
|
353
385
|
`);
|
|
354
386
|
expect(trimmed).not.toContain("URL is private");
|
|
@@ -365,6 +397,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
365
397
|
expect(trimmed).not.toContain("unknown");
|
|
366
398
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
367
399
|
"
|
|
400
|
+
└── b/src
|
|
401
|
+
└── hello.ts (+1,-1)
|
|
402
|
+
|
|
403
|
+
|
|
368
404
|
a/src/hello.ts → b/src/hello.ts +1-1
|
|
369
405
|
|
|
370
406
|
1 const greeting = 'hello'
|
|
@@ -381,6 +417,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
381
417
|
const trimmed = await session.text({ trimEnd: true });
|
|
382
418
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
383
419
|
"
|
|
420
|
+
└── b/src
|
|
421
|
+
└── hello.ts (+1,-1)
|
|
422
|
+
|
|
423
|
+
|
|
384
424
|
a/src/hello.ts → b/src/hello.ts +1-1
|
|
385
425
|
|
|
386
426
|
1 const greeting = 'hello'
|
package/package.json
CHANGED
package/src/diff-utils.test.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { parsePatch, formatPatch } from "diff"
|
|
|
8
8
|
import {
|
|
9
9
|
preprocessDiff,
|
|
10
10
|
parseGitDiffFiles,
|
|
11
|
+
processFiles,
|
|
11
12
|
getFileStatus,
|
|
12
13
|
getFileName,
|
|
13
14
|
getOldFileName,
|
|
@@ -19,6 +20,82 @@ import {
|
|
|
19
20
|
detectFiletype,
|
|
20
21
|
} from "./diff-utils.js"
|
|
21
22
|
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// processFiles ordering
|
|
25
|
+
// ============================================================================
|
|
26
|
+
|
|
27
|
+
describe("processFiles ordering", () => {
|
|
28
|
+
it("should order output files to match directory tree traversal", () => {
|
|
29
|
+
const files = [
|
|
30
|
+
{
|
|
31
|
+
oldFileName: "src/components/button.tsx",
|
|
32
|
+
newFileName: "src/components/button.tsx",
|
|
33
|
+
hunks: [{ lines: Array.from({ length: 90 }, () => "+line") }],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
oldFileName: "src/index.ts",
|
|
37
|
+
newFileName: "src/index.ts",
|
|
38
|
+
hunks: [{ lines: ["+line"] }],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
oldFileName: "README.md",
|
|
42
|
+
newFileName: "README.md",
|
|
43
|
+
hunks: [{ lines: ["+line", "+line", "+line"] }],
|
|
44
|
+
},
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
const processed = processFiles(
|
|
48
|
+
files,
|
|
49
|
+
(file) => `diff --git ${file.oldFileName} ${file.newFileName}`,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
expect(processed.map((file) => getFileName(file))).toEqual([
|
|
53
|
+
"README.md",
|
|
54
|
+
"src/components/button.tsx",
|
|
55
|
+
"src/index.ts",
|
|
56
|
+
])
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it("should keep tree order with renamed, added, and deleted files", () => {
|
|
60
|
+
const files = [
|
|
61
|
+
{
|
|
62
|
+
oldFileName: "src/alpha.ts",
|
|
63
|
+
newFileName: "src/alpha.ts",
|
|
64
|
+
hunks: [{ lines: Array.from({ length: 30 }, () => "+line") }],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
oldFileName: "docs/old-name.md",
|
|
68
|
+
newFileName: "docs/new-name.md",
|
|
69
|
+
renameFrom: "docs/old-name.md",
|
|
70
|
+
renameTo: "docs/new-name.md",
|
|
71
|
+
hunks: [{ lines: ["+line"] }],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
oldFileName: "/dev/null",
|
|
75
|
+
newFileName: "docs/guide.md",
|
|
76
|
+
hunks: [{ lines: ["+line", "+line"] }],
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
oldFileName: "src/remove.ts",
|
|
80
|
+
newFileName: "/dev/null",
|
|
81
|
+
hunks: [{ lines: ["-line"] }],
|
|
82
|
+
},
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
const processed = processFiles(
|
|
86
|
+
files,
|
|
87
|
+
(file) => `diff --git ${file.oldFileName} ${file.newFileName}`,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
expect(processed.map((file) => getFileName(file))).toEqual([
|
|
91
|
+
"docs/guide.md",
|
|
92
|
+
"docs/new-name.md",
|
|
93
|
+
"src/alpha.ts",
|
|
94
|
+
"src/remove.ts",
|
|
95
|
+
])
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
22
99
|
// ============================================================================
|
|
23
100
|
// preprocessDiff
|
|
24
101
|
// ============================================================================
|
package/src/diff-utils.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// and provides helpers for unified/split view mode selection.
|
|
4
4
|
|
|
5
5
|
import { execSync } from "child_process"
|
|
6
|
+
import { buildDirectoryTree } from "./directory-tree.js"
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Strip submodule status lines from git diff output.
|
|
@@ -515,11 +516,41 @@ export function processFiles<T extends ParsedFile>(
|
|
|
515
516
|
return totalLines <= 6000;
|
|
516
517
|
});
|
|
517
518
|
|
|
518
|
-
const
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
519
|
+
const treeFiles = filteredFiles.map((file, index) => {
|
|
520
|
+
const { additions, deletions } = countChanges(file.hunks)
|
|
521
|
+
return {
|
|
522
|
+
path: getFileName(file),
|
|
523
|
+
status: getFileStatus(file),
|
|
524
|
+
additions,
|
|
525
|
+
deletions,
|
|
526
|
+
fileIndex: index,
|
|
527
|
+
}
|
|
528
|
+
})
|
|
529
|
+
|
|
530
|
+
const treeFileOrder = buildDirectoryTree(treeFiles)
|
|
531
|
+
.filter((node) => node.isFile && node.fileIndex !== undefined)
|
|
532
|
+
.map((node) => node.fileIndex!)
|
|
533
|
+
|
|
534
|
+
const seenIndexes = new Set<number>()
|
|
535
|
+
const sortedFiles: T[] = []
|
|
536
|
+
|
|
537
|
+
for (const index of treeFileOrder) {
|
|
538
|
+
if (seenIndexes.has(index)) continue
|
|
539
|
+
const file = filteredFiles[index]
|
|
540
|
+
if (!file) continue
|
|
541
|
+
seenIndexes.add(index)
|
|
542
|
+
sortedFiles.push(file)
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Defensive fallback: keep any unmatched files in original order.
|
|
546
|
+
// This should be rare, but avoids dropping files if tree metadata and
|
|
547
|
+
// parsed file list ever diverge.
|
|
548
|
+
for (let index = 0; index < filteredFiles.length; index++) {
|
|
549
|
+
if (seenIndexes.has(index)) continue
|
|
550
|
+
const file = filteredFiles[index]
|
|
551
|
+
if (!file) continue
|
|
552
|
+
sortedFiles.push(file)
|
|
553
|
+
}
|
|
523
554
|
|
|
524
555
|
// Add rawDiff for each file
|
|
525
556
|
return sortedFiles.map((file) => ({
|
|
@@ -60,6 +60,31 @@ describe("buildDirectoryTree", () => {
|
|
|
60
60
|
expect(result[1]!.displayPath).toBe("Button.tsx")
|
|
61
61
|
expect(result[1]!.isFile).toBe(true)
|
|
62
62
|
})
|
|
63
|
+
|
|
64
|
+
it("should sort nodes alphabetically regardless of input order", () => {
|
|
65
|
+
const files: TreeFileInfo[] = [
|
|
66
|
+
{ path: "website/src/index.ts", status: "modified", additions: 1, deletions: 0 },
|
|
67
|
+
{ path: "db/schema.prisma", status: "modified", additions: 1, deletions: 0 },
|
|
68
|
+
{ path: "discord/src/utils.ts", status: "modified", additions: 1, deletions: 0 },
|
|
69
|
+
{ path: "discord/src/cli.ts", status: "modified", additions: 1, deletions: 0 },
|
|
70
|
+
{ path: "gateway-proxy/src/main.rs", status: "modified", additions: 1, deletions: 0 },
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
const result = buildDirectoryTree(files)
|
|
74
|
+
|
|
75
|
+
const rendered = result.map((node) => `${node.prefix}${node.connector}${node.displayPath}`)
|
|
76
|
+
expect(rendered).toEqual([
|
|
77
|
+
"├── db",
|
|
78
|
+
"│ └── schema.prisma",
|
|
79
|
+
"├── discord/src",
|
|
80
|
+
"│ ├── cli.ts",
|
|
81
|
+
"│ └── utils.ts",
|
|
82
|
+
"├── gateway-proxy/src",
|
|
83
|
+
"│ └── main.rs",
|
|
84
|
+
"└── website/src",
|
|
85
|
+
" └── index.ts",
|
|
86
|
+
])
|
|
87
|
+
})
|
|
63
88
|
})
|
|
64
89
|
|
|
65
90
|
describe("TreeRenderer visual tests", () => {
|
|
@@ -199,10 +224,10 @@ describe("TreeRenderer visual tests", () => {
|
|
|
199
224
|
expect(frame).toMatchInlineSnapshot(`
|
|
200
225
|
"├── package.json (+2,-1)
|
|
201
226
|
├── src
|
|
202
|
-
│ ├── index.ts (+10,-5)
|
|
203
227
|
│ ├── components
|
|
204
228
|
│ │ ├── Button.tsx (+50,-0)
|
|
205
229
|
│ │ └── Input.tsx (+15,-8)
|
|
230
|
+
│ ├── index.ts (+10,-5)
|
|
206
231
|
│ └── utils
|
|
207
232
|
│ └── helpers.ts (+0,-30)
|
|
208
233
|
└── tests
|
|
@@ -233,8 +258,8 @@ describe("TreeRenderer visual tests", () => {
|
|
|
233
258
|
const frame = testSetup.captureCharFrame()
|
|
234
259
|
expect(frame).toMatchInlineSnapshot(`
|
|
235
260
|
"└── packages/core/src/lib/utils
|
|
236
|
-
├──
|
|
237
|
-
└──
|
|
261
|
+
├── format.ts (+20,-0)
|
|
262
|
+
└── helpers.ts (+5,-3)
|
|
238
263
|
|
|
239
264
|
|
|
240
265
|
|
|
@@ -261,14 +286,14 @@ describe("TreeRenderer visual tests", () => {
|
|
|
261
286
|
await testSetup.renderOnce()
|
|
262
287
|
const frame = testSetup.captureCharFrame()
|
|
263
288
|
expect(frame).toMatchInlineSnapshot(`
|
|
264
|
-
"├──
|
|
265
|
-
│
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
289
|
+
"├── lib
|
|
290
|
+
│ └── utils.ts (+15,-0)
|
|
291
|
+
└── src
|
|
292
|
+
├── api
|
|
293
|
+
│ ├── handlers.ts (+30,-0)
|
|
294
|
+
│ └── routes.ts (+10,-5)
|
|
295
|
+
└── db
|
|
296
|
+
└── models.ts (+8,-2)
|
|
272
297
|
|
|
273
298
|
|
|
274
299
|
|
|
@@ -303,10 +328,10 @@ describe("DirectoryTreeView component", () => {
|
|
|
303
328
|
await testSetup.renderOnce()
|
|
304
329
|
const frame = testSetup.captureCharFrame()
|
|
305
330
|
expect(frame).toMatchInlineSnapshot(`
|
|
306
|
-
" ├──
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
331
|
+
" ├── README.md (-15)
|
|
332
|
+
└── src
|
|
333
|
+
├── index.ts (+5,-2)
|
|
334
|
+
└── utils.ts (+30)
|
|
310
335
|
|
|
311
336
|
|
|
312
337
|
|
package/src/directory-tree.ts
CHANGED
|
@@ -62,6 +62,7 @@ export function buildDirectoryTree(files: TreeFileInfo[]): TreeNode[] {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
const tree = buildInternalTree(files)
|
|
65
|
+
sortInternalTree(tree)
|
|
65
66
|
return flattenTree(tree)
|
|
66
67
|
}
|
|
67
68
|
|
|
@@ -115,6 +116,19 @@ function getName(node: InternalTreeNode): string {
|
|
|
115
116
|
return parts[parts.length - 1] || node.path
|
|
116
117
|
}
|
|
117
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Sort tree nodes by name at every level so file ordering is deterministic
|
|
121
|
+
* and independent from incoming git diff section order.
|
|
122
|
+
*/
|
|
123
|
+
function sortInternalTree(nodes: InternalTreeNode[]): void {
|
|
124
|
+
nodes.sort((a, b) => getName(a).toLowerCase().localeCompare(getName(b).toLowerCase()))
|
|
125
|
+
for (const node of nodes) {
|
|
126
|
+
if (node.children.length > 0) {
|
|
127
|
+
sortInternalTree(node.children)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
118
132
|
/**
|
|
119
133
|
* Collapse directories that only contain a single subdirectory (no files)
|
|
120
134
|
*/
|
package/src/stdin-pager.test.ts
CHANGED
|
@@ -194,6 +194,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
194
194
|
|
|
195
195
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
196
196
|
"
|
|
197
|
+
└── b/src
|
|
198
|
+
└── hello.ts (+1,-1)
|
|
199
|
+
|
|
200
|
+
|
|
197
201
|
a/src/hello.ts → b/src/hello.ts +1-1
|
|
198
202
|
|
|
199
203
|
1 const greeting = 'hello'
|
|
@@ -235,6 +239,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
235
239
|
|
|
236
240
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
237
241
|
"
|
|
242
|
+
└── b
|
|
243
|
+
└── readme.md ()
|
|
244
|
+
|
|
245
|
+
|
|
238
246
|
a/readme.md → b/readme.md +0-0
|
|
239
247
|
|
|
240
248
|
1 # My Project
|
|
@@ -253,6 +261,11 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
253
261
|
|
|
254
262
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
255
263
|
"
|
|
264
|
+
└── b/src
|
|
265
|
+
├── logger.ts (+5)
|
|
266
|
+
└── index.ts (+2)
|
|
267
|
+
|
|
268
|
+
|
|
256
269
|
b/src/logger.ts +5-0
|
|
257
270
|
|
|
258
271
|
1 + export class Logger {
|
|
@@ -292,6 +305,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
292
305
|
|
|
293
306
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
294
307
|
"
|
|
308
|
+
└── a/src
|
|
309
|
+
└── deprecated.ts (-4)
|
|
310
|
+
|
|
311
|
+
|
|
295
312
|
a/src/deprecated.ts +0-4
|
|
296
313
|
|
|
297
314
|
1 - // This module is no longer needed
|
|
@@ -313,6 +330,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
313
330
|
|
|
314
331
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
315
332
|
"
|
|
333
|
+
└── b/src
|
|
334
|
+
└── utils.ts (+7)
|
|
335
|
+
|
|
336
|
+
|
|
316
337
|
b/src/utils.ts +7-0
|
|
317
338
|
|
|
318
339
|
1 + export function clamp(value: number, min: number, max: number): number {
|
|
@@ -338,6 +359,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
338
359
|
|
|
339
360
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
340
361
|
"
|
|
362
|
+
└── b
|
|
363
|
+
└── config.json (+6,-4)
|
|
364
|
+
|
|
365
|
+
|
|
341
366
|
a/config.json → b/config.json +6-4
|
|
342
367
|
|
|
343
368
|
1 {
|
|
@@ -371,6 +396,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
371
396
|
|
|
372
397
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
373
398
|
"
|
|
399
|
+
└── src
|
|
400
|
+
└── new-name.ts (+1,-1)
|
|
401
|
+
|
|
402
|
+
|
|
374
403
|
src/old-name.ts → src/new-name.ts +1-1
|
|
375
404
|
|
|
376
405
|
1 - export const name = 'old'
|
|
@@ -396,6 +425,9 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
396
425
|
|
|
397
426
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
398
427
|
"
|
|
428
|
+
└── unknown ()
|
|
429
|
+
|
|
430
|
+
|
|
399
431
|
unknown +0-0"
|
|
400
432
|
`)
|
|
401
433
|
|
|
@@ -416,6 +448,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
416
448
|
|
|
417
449
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
418
450
|
"
|
|
451
|
+
└── b/src
|
|
452
|
+
└── hello.ts (+1,-1)
|
|
453
|
+
|
|
454
|
+
|
|
419
455
|
a/src/hello.ts → b/src/hello.ts +1-1
|
|
420
456
|
|
|
421
457
|
1 const greeting = 'hello'
|
|
@@ -435,6 +471,10 @@ describe("--stdin pager mode (lazygit issue #25)", () => {
|
|
|
435
471
|
|
|
436
472
|
expect(trimmed).toMatchInlineSnapshot(`
|
|
437
473
|
"
|
|
474
|
+
└── b/src
|
|
475
|
+
└── hello.ts (+1,-1)
|
|
476
|
+
|
|
477
|
+
|
|
438
478
|
a/src/hello.ts → b/src/hello.ts +1-1
|
|
439
479
|
|
|
440
480
|
1 const greeting = 'hello'
|