diff --git a/src/git.test.ts b/src/git.test.ts index feaf9f3..c125f2d 100644 --- a/src/git.test.ts +++ b/src/git.test.ts @@ -4,7 +4,7 @@ import { getDiffFileList, getDiffForFile, getRangesForDiff, - getUntrackedFileList, + getTrackedFileList, hasCleanIndex, } from "./git"; import { @@ -142,33 +142,18 @@ describe("getDiffFileList", () => { }); }); -describe("getUntrackedFileList", () => { +describe("getTrackedFileList", () => { it("should get the list of untracked files", () => { jest.mock("child_process").resetAllMocks(); mockedChildProcess.execFileSync.mockReturnValueOnce( Buffer.from(diffFileList) ); expect(mockedChildProcess.execFileSync).toHaveBeenCalledTimes(0); - const fileListA = getUntrackedFileList(false); - expect(mockedChildProcess.execFileSync).toHaveBeenCalledTimes(1); - - mockedChildProcess.execFileSync.mockReturnValueOnce( - Buffer.from(diffFileList) - ); - const staged = false; - const fileListB = getUntrackedFileList(staged); - // `getUntrackedFileList` uses a cache, so the number of calls to - // `execFileSync` will not have increased. + const fileListA = getTrackedFileList(); expect(mockedChildProcess.execFileSync).toHaveBeenCalledTimes(1); expect(fileListA).toEqual( ["file1", "file2", "file3"].map((p) => path.resolve(p)) ); - expect(fileListA).toEqual(fileListB); - }); - - it("should not get a list when looking when using staged", () => { - const staged = true; - expect(getUntrackedFileList(staged)).toEqual([]); }); }); diff --git a/src/git.ts b/src/git.ts index 747f59c..aba1295 100644 --- a/src/git.ts +++ b/src/git.ts @@ -51,6 +51,17 @@ const getDiffFileList = (staged: boolean): string[] => { .map((filePath) => resolve(filePath)); }; +const getTrackedFileList = (): string[] => { + const args = [ "ls-files" ]; + + return child_process + .execFileSync(COMMAND, args, OPTIONS) + .toString() + .trim() + .split("\n") + .map((filePath) => resolve(filePath)) +}; + const hasCleanIndex = (filePath: string): boolean => { const args = [ "diff", @@ -77,29 +88,6 @@ const fetchFromOrigin = (branch: string) => { child_process.execFileSync(COMMAND, args, OPTIONS); }; -let untrackedFileListCache: string[] | undefined; -const getUntrackedFileList = ( - staged: boolean, - shouldRefresh = false -): string[] => { - if (staged) { - return []; - } - - if (untrackedFileListCache === undefined || shouldRefresh) { - const args = ["ls-files", "--exclude-standard", "--others"]; - - untrackedFileListCache = child_process - .execFileSync(COMMAND, args, OPTIONS) - .toString() - .trim() - .split("\n") - .map((filePath) => resolve(filePath)); - } - - return untrackedFileListCache; -}; - const isHunkHeader = (input: string) => { const hunkHeaderRE = /^@@ [^@]* @@/u; @@ -160,6 +148,6 @@ export { getDiffFileList, getDiffForFile, getRangesForDiff, - getUntrackedFileList, + getTrackedFileList, hasCleanIndex, }; diff --git a/src/processors.test.ts b/src/processors.test.ts index 0d3b37d..170d70d 100644 --- a/src/processors.test.ts +++ b/src/processors.test.ts @@ -1,6 +1,6 @@ jest.mock("./git", () => ({ ...jest.requireActual("./git"), - getUntrackedFileList: jest.fn(), + getTrackedFileList: jest.fn(), getDiffFileList: jest.fn(), getDiffForFile: jest.fn(), hasCleanIndex: jest.fn(), @@ -19,7 +19,7 @@ const untrackedFilename = "an-untracked-file.js"; const gitMocked: jest.MockedObjectDeep = jest.mocked(git); gitMocked.getDiffFileList.mockReturnValue([filename]); -gitMocked.getUntrackedFileList.mockReturnValue([untrackedFilename]); +gitMocked.getTrackedFileList.mockReturnValue([filename, "file-with-dirty-index.js"]); describe("processors", () => { it("preprocess (diff and staged)", async () => { diff --git a/src/processors.ts b/src/processors.ts index 8b63e79..d5e2533 100644 --- a/src/processors.ts +++ b/src/processors.ts @@ -5,7 +5,7 @@ import { getDiffFileList, getDiffForFile, getRangesForDiff, - getUntrackedFileList, + getTrackedFileList, hasCleanIndex, } from "./git"; import type { Range } from "./Range"; @@ -28,18 +28,12 @@ if (process.env.CI !== undefined) { * This is increasingly useful the more files there are in the repository. */ const getPreProcessor = - (diffFileList: string[], staged: boolean) => + (trackedFileSet: Set, diffFileList: string[]) => (text: string, filename: string) => { - let untrackedFileList = getUntrackedFileList(staged); - const shouldRefresh = - !diffFileList.includes(filename) && !untrackedFileList.includes(filename); - if (shouldRefresh) { - untrackedFileList = getUntrackedFileList(staged, true); - } const shouldBeProcessed = process.env.VSCODE_PID !== undefined || diffFileList.includes(filename) || - untrackedFileList.includes(filename); + !trackedFileSet.has(filename); return shouldBeProcessed ? [text] : []; }; @@ -72,7 +66,7 @@ const getUnstagedChangesError = (filename: string): [Linter.LintMessage] => { }; const getPostProcessor = - (staged: boolean) => + (trackedFileSet: Set, staged: boolean) => ( messages: Linter.LintMessage[][], filename: string @@ -81,8 +75,7 @@ const getPostProcessor = // No need to filter, just return return []; } - const untrackedFileList = getUntrackedFileList(staged); - if (untrackedFileList.includes(filename)) { + if (!trackedFileSet.has(filename)) { // We don't need to filter the messages of untracked files because they // would all be kept anyway, so we return them as-is. return messages.flat(); @@ -117,11 +110,12 @@ const getProcessors = ( processorType: ProcessorType ): Required => { const staged = processorType === "staged"; + const trackedFileSet = new Set(getTrackedFileList()); const diffFileList = getDiffFileList(staged); return { - preprocess: getPreProcessor(diffFileList, staged), - postprocess: getPostProcessor(staged), + preprocess: getPreProcessor(trackedFileSet, diffFileList), + postprocess: getPostProcessor(trackedFileSet, staged), supportsAutofix: true, }; };