From fa15d686deb90b7ffddfbcf644d56ed05fcd8a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iiro=20J=C3=A4ppinen?= Date: Tue, 22 Feb 2022 21:09:29 +0200 Subject: [PATCH] refactor: extract `parseGitZOutput` util --- lib/getStagedFiles.js | 11 ++--------- lib/parseGitZOutput.js | 9 +++++++++ lib/searchConfigs.js | 17 ++++++----------- test/parseGitZOutput.spec.js | 13 +++++++++++++ 4 files changed, 30 insertions(+), 20 deletions(-) create mode 100644 lib/parseGitZOutput.js create mode 100644 test/parseGitZOutput.spec.js 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']) + }) +})