fix(git-worktree): use Node readFileSync for cross-platform untracked file line counts
This commit is contained in:
parent
0e49214ee7
commit
554926209d
@ -7,9 +7,6 @@ const execSyncMock = mock(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const execFileSyncMock = mock((file: string, args: string[], _opts: { cwd?: string }) => {
|
const execFileSyncMock = mock((file: string, args: string[], _opts: { cwd?: string }) => {
|
||||||
if (file === "wc") {
|
|
||||||
return " 10 new-file.ts\n"
|
|
||||||
}
|
|
||||||
if (file !== "git") throw new Error(`unexpected file: ${file}`)
|
if (file !== "git") throw new Error(`unexpected file: ${file}`)
|
||||||
const subcommand = args[0]
|
const subcommand = args[0]
|
||||||
|
|
||||||
@ -28,11 +25,19 @@ const execFileSyncMock = mock((file: string, args: string[], _opts: { cwd?: stri
|
|||||||
throw new Error(`unexpected args: ${args.join(" ")}`)
|
throw new Error(`unexpected args: ${args.join(" ")}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const readFileSyncMock = mock((_path: string, _encoding: string) => {
|
||||||
|
return "line1\nline2\nline3\nline4\nline5\nline6\nline7\nline8\nline9\nline10\n"
|
||||||
|
})
|
||||||
|
|
||||||
mock.module("node:child_process", () => ({
|
mock.module("node:child_process", () => ({
|
||||||
execSync: execSyncMock,
|
execSync: execSyncMock,
|
||||||
execFileSync: execFileSyncMock,
|
execFileSync: execFileSyncMock,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
mock.module("node:fs", () => ({
|
||||||
|
readFileSync: readFileSyncMock,
|
||||||
|
}))
|
||||||
|
|
||||||
const { collectGitDiffStats } = await import("./collect-git-diff-stats")
|
const { collectGitDiffStats } = await import("./collect-git-diff-stats")
|
||||||
|
|
||||||
describe("collectGitDiffStats", () => {
|
describe("collectGitDiffStats", () => {
|
||||||
@ -45,7 +50,7 @@ describe("collectGitDiffStats", () => {
|
|||||||
|
|
||||||
//#then
|
//#then
|
||||||
expect(execSyncMock).not.toHaveBeenCalled()
|
expect(execSyncMock).not.toHaveBeenCalled()
|
||||||
expect(execFileSyncMock).toHaveBeenCalledTimes(4)
|
expect(execFileSyncMock).toHaveBeenCalledTimes(3)
|
||||||
|
|
||||||
const [firstCallFile, firstCallArgs, firstCallOpts] = execFileSyncMock.mock
|
const [firstCallFile, firstCallArgs, firstCallOpts] = execFileSyncMock.mock
|
||||||
.calls[0]! as unknown as [string, string[], { cwd?: string }]
|
.calls[0]! as unknown as [string, string[], { cwd?: string }]
|
||||||
@ -68,11 +73,7 @@ describe("collectGitDiffStats", () => {
|
|||||||
expect(thirdCallOpts.cwd).toBe(directory)
|
expect(thirdCallOpts.cwd).toBe(directory)
|
||||||
expect(thirdCallArgs.join(" ")).not.toContain(directory)
|
expect(thirdCallArgs.join(" ")).not.toContain(directory)
|
||||||
|
|
||||||
const [fourthCallFile, fourthCallArgs, fourthCallOpts] = execFileSyncMock.mock
|
expect(readFileSyncMock).toHaveBeenCalled()
|
||||||
.calls[3]! as unknown as [string, string[], { cwd?: string }]
|
|
||||||
expect(fourthCallFile).toBe("wc")
|
|
||||||
expect(fourthCallArgs).toEqual(["-l", "--", "new-file.ts"])
|
|
||||||
expect(fourthCallOpts.cwd).toBe(directory)
|
|
||||||
|
|
||||||
expect(result).toEqual([
|
expect(result).toEqual([
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
import { execFileSync } from "node:child_process"
|
import { execFileSync } from "node:child_process"
|
||||||
|
import { readFileSync } from "node:fs"
|
||||||
|
import { join } from "node:path"
|
||||||
import { parseGitStatusPorcelain } from "./parse-status-porcelain"
|
import { parseGitStatusPorcelain } from "./parse-status-porcelain"
|
||||||
import { parseGitDiffNumstat } from "./parse-diff-numstat"
|
import { parseGitDiffNumstat } from "./parse-diff-numstat"
|
||||||
import type { GitFileStat } from "./types"
|
import type { GitFileStat } from "./types"
|
||||||
@ -32,17 +34,8 @@ export function collectGitDiffStats(directory: string): GitFileStat[] {
|
|||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.map((filePath) => {
|
.map((filePath) => {
|
||||||
try {
|
try {
|
||||||
const wcOutput = execFileSync("wc", ["-l", "--", filePath], {
|
const content = readFileSync(join(directory, filePath), "utf-8")
|
||||||
cwd: directory,
|
const lineCount = content.split("\n").length - (content.endsWith("\n") ? 1 : 0)
|
||||||
encoding: "utf-8",
|
|
||||||
timeout: 5000,
|
|
||||||
stdio: ["pipe", "pipe", "pipe"],
|
|
||||||
}).trim()
|
|
||||||
|
|
||||||
const [lineCountToken] = wcOutput.split(/\s+/)
|
|
||||||
const lineCount = Number(lineCountToken)
|
|
||||||
if (!Number.isFinite(lineCount)) return `0\t0\t${filePath}`
|
|
||||||
|
|
||||||
return `${lineCount}\t0\t${filePath}`
|
return `${lineCount}\t0\t${filePath}`
|
||||||
} catch {
|
} catch {
|
||||||
return `0\t0\t${filePath}`
|
return `0\t0\t${filePath}`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user