diff --git a/lib/getStagedFiles.js b/lib/getStagedFiles.js index a6a557383..363e07a1d 100644 --- a/lib/getStagedFiles.js +++ b/lib/getStagedFiles.js @@ -3,6 +3,7 @@ import path from 'path' import normalize from 'normalize-path' import { execGit } from './execGit.js' +import { parseGitZOutput } from './parseGitZOutput.js' export const getStagedFiles = async ({ cwd = process.cwd() } = {}) => { try { @@ -14,15 +15,7 @@ export const getStagedFiles = async ({ cwd = process.cwd() } = {}) => { if (!lines) return [] - // With `-z`, git prints `fileA\u0000fileB\u0000fileC\u0000` so we need to - // remove the last occurrence of `\u0000` before splitting - return ( - lines - // eslint-disable-next-line no-control-regex - .replace(/\u0000$/, '') - .split('\u0000') - .map((file) => normalize(path.resolve(cwd, file))) - ) + return parseGitZOutput(lines).map((file) => normalize(path.resolve(cwd, file))) } catch { return null } diff --git a/lib/parseGitZOutput.js b/lib/parseGitZOutput.js new file mode 100644 index 000000000..931e1639f --- /dev/null +++ b/lib/parseGitZOutput.js @@ -0,0 +1,9 @@ +/** + * Return array of strings split from the output of `git -z`. + * With `-z`, git prints `fileA\u0000fileB\u0000fileC\u0000` so we need to + * remove the last occurrence of `\u0000` before splitting + */ +export const parseGitZOutput = (input) => + input + .replace(/\u0000$/, '') // eslint-disable-line no-control-regex + .split('\u0000') diff --git a/lib/searchConfigs.js b/lib/searchConfigs.js index 063e0e29d..bfca1c4e3 100644 --- a/lib/searchConfigs.js +++ b/lib/searchConfigs.js @@ -6,6 +6,7 @@ import normalize from 'normalize-path' import { execGit } from './execGit.js' import { loadConfig, searchPlaces } from './loadConfig.js' +import { parseGitZOutput } from './parseGitZOutput.js' import { validateConfig } from './validateConfig.js' const EXEC_GIT = ['ls-files', '-z', '--full-name'] @@ -25,20 +26,14 @@ const sortDeepestParth = (a, b) => (numberOfLevels(a) > numberOfLevels(b) ? -1 : */ export const searchConfigs = async (gitDir = process.cwd(), logger) => { /** Get all possible config files known to git */ - const cachedFiles = (await execGit(EXEC_GIT, { cwd: gitDir })) - // eslint-disable-next-line no-control-regex - .replace(/\u0000$/, '') - .split('\u0000') - .filter(filterPossibleConfigFiles) + const cachedFiles = parseGitZOutput(await execGit(EXEC_GIT, { cwd: gitDir })).filter( + filterPossibleConfigFiles + ) /** Get all possible config files from uncommitted files */ - const otherFiles = ( + const otherFiles = parseGitZOutput( await execGit([...EXEC_GIT, '--others', '--exclude-standard'], { cwd: gitDir }) - ) - // eslint-disable-next-line no-control-regex - .replace(/\u0000$/, '') - .split('\u0000') - .filter(filterPossibleConfigFiles) + ).filter(filterPossibleConfigFiles) /** Sort possible config files so that deepest is first */ const possibleConfigFiles = [...cachedFiles, ...otherFiles] diff --git a/test/parseGitZOutput.spec.js b/test/parseGitZOutput.spec.js new file mode 100644 index 000000000..772921ad1 --- /dev/null +++ b/test/parseGitZOutput.spec.js @@ -0,0 +1,13 @@ +import { parseGitZOutput } from '../lib/parseGitZOutput' + +describe('parseGitZOutput', () => { + it('should split string from `git -z` control character', () => { + const input = 'a\u0000b\u0000c' + expect(parseGitZOutput(input)).toEqual(['a', 'b', 'c']) + }) + + it('should remove trailing `git -z` control character', () => { + const input = 'a\u0000' + expect(parseGitZOutput(input)).toEqual(['a']) + }) +})