Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: apply ignore settings when copying file #745

Merged
merged 4 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 81 additions & 26 deletions __tests__/unit/lib/utils/fsHelper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import {
scanExtension,
writeFile,
} from '../../../../src/utils/fsHelper'
import {
IgnoreHelper,
buildIgnoreHelper,
} from '../../../../src/utils/ignoreHelper'
import {
getSpawnContent,
treatPathSep,
Expand All @@ -28,6 +32,7 @@ import {
import { EOL } from 'os'
import { Work } from '../../../../src/types/work'
import { Config } from '../../../../src/types/config'
import { Ignore } from 'ignore'

jest.mock('fs-extra')
jest.mock('../../../../src/utils/gitLfsHelper')
Expand All @@ -42,7 +47,9 @@ jest.mock('../../../../src/utils/childProcessUtils', () => {
treatPathSep: jest.fn(),
}
})
jest.mock('../../../../src/utils/ignoreHelper')

const mockBuildIgnoreHelper = jest.mocked(buildIgnoreHelper)
const mockedGetStreamContent = jest.mocked(getSpawnContent)
const mockedTreatPathSep = jest.mocked(treatPathSep)
const mockedStat = jest.mocked(stat)
Expand All @@ -54,7 +61,7 @@ beforeEach(() => {
jest.resetAllMocks()
work = getWork()
work.config.from = 'pastsha'
work.config.from = 'recentsha'
work.config.to = 'recentsha'
})

describe('gitPathSeparatorNormalizer', () => {
Expand Down Expand Up @@ -135,6 +142,13 @@ describe('readPathFromGit', () => {
})

describe('copyFile', () => {
beforeEach(() => {
mockBuildIgnoreHelper.mockResolvedValue({
globalIgnore: {
ignores: () => false,
} as unknown as Ignore,
} as unknown as IgnoreHelper)
})
describe('when file is already copied', () => {
it('should not copy file', async () => {
await copyFiles(work.config, 'source/file')
Expand Down Expand Up @@ -165,25 +179,61 @@ describe('copyFile', () => {
})
})

describe('when source location is empty', () => {
it('should copy file', async () => {
describe('when content is not a git location', () => {
it('should ignore this path', async () => {
// Arrange
mockedTreatPathSep.mockReturnValueOnce('source/copyFile')
mockedGetStreamContent.mockResolvedValue(Buffer.from(''))
const sourcePath = 'source/warning'
mockedGetStreamContent.mockRejectedValue(
`fatal: path '${sourcePath}' does not exist in 'HEAD'`
)

// Act
await copyFiles(work.config, 'source/doNotCopy')
await copyFiles(work.config, sourcePath)

// Assert
expect(getSpawnContent).toBeCalled()
expect(outputFile).toBeCalledWith(
'output/source/copyFile',
Buffer.from('')
)
expect(outputFile).not.toBeCalled()
})
})

describe('when source location is not empty', () => {
describe('when path is ignored', () => {
it('should not copy this path', async () => {
// Arrange
mockBuildIgnoreHelper.mockResolvedValue({
globalIgnore: {
ignores: () => true,
} as unknown as Ignore,
} as unknown as IgnoreHelper)

// Act
await copyFiles(work.config, 'source/ignored')

// Assert
expect(getSpawnContent).not.toBeCalled()
expect(outputFile).not.toBeCalled()
})
})

describe('when content should be copied', () => {
describe('when source location is empty', () => {
it('should copy file', async () => {
// Arrange

mockedTreatPathSep.mockReturnValueOnce('source/copyFile')
mockedGetStreamContent.mockResolvedValue(Buffer.from(''))

// Act
await copyFiles(work.config, 'source/doNotCopy')

// Assert
expect(getSpawnContent).toBeCalled()
expect(outputFile).toBeCalledWith(
'output/source/copyFile',
Buffer.from('')
)
})
})

describe('when content is a folder', () => {
it('should copy the folder', async () => {
// Arrange
Expand All @@ -206,22 +256,7 @@ describe('copyFile', () => {
expect(treatPathSep).toBeCalledTimes(1)
})
})
describe('when content is not a git location', () => {
it('should ignore this path', async () => {
// Arrange
const sourcePath = 'source/warning'
mockedGetStreamContent.mockRejectedValue(
`fatal: path '${sourcePath}' does not exist in 'HEAD'`
)

// Act
await copyFiles(work.config, sourcePath)

// Assert
expect(getSpawnContent).toBeCalled()
expect(outputFile).not.toBeCalled()
})
})
describe('when content is a file', () => {
beforeEach(async () => {
// Arrange
Expand Down Expand Up @@ -549,6 +584,11 @@ describe('pathExists', () => {
describe('writeFile', () => {
beforeEach(() => {
mockedTreatPathSep.mockReturnValue('folder/file')
mockBuildIgnoreHelper.mockResolvedValue({
globalIgnore: {
ignores: () => false,
} as unknown as Ignore,
} as unknown as IgnoreHelper)
})

it.each(['folder/file', 'folder\\file'])(
Expand Down Expand Up @@ -581,6 +621,21 @@ describe('writeFile', () => {
// Assert
expect(outputFile).toBeCalledTimes(1)
})

it('should not copy ignored path', async () => {
// Arrange
mockBuildIgnoreHelper.mockResolvedValue({
globalIgnore: {
ignores: () => true,
} as unknown as Ignore,
} as unknown as IgnoreHelper)

// Act
await writeFile('', '', {} as Config)

// Assert
expect(outputFile).not.toBeCalled()
})
})

describe('dirExists', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/post-processor/flowTranslationProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export default class FlowTranslationProcessor extends BaseProcessor {

for (const translationPath of translationsIterator) {
if (
!ignoreHelper?.globalIgnore?.ignores(translationPath) &&
!ignoreHelper.globalIgnore.ignores(translationPath) &&
!isSubDir(this.config.output, translationPath)
) {
await this._parseTranslationFile(translationPath)
Expand Down
25 changes: 19 additions & 6 deletions src/utils/fsHelper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'
import { readFile as fsReadFile } from 'fs-extra'
import { isAbsolute, join, relative } from 'path'
import { outputFile, stat } from 'fs-extra'
import { readFile as fsReadFile, outputFile, stat } from 'fs-extra'
import {
GIT_COMMAND,
GIT_FOLDER,
Expand All @@ -10,6 +9,7 @@ import {
} from './gitConstants'
import { EOLRegex, getSpawnContent, treatPathSep } from './childProcessUtils'
import { isLFS, getLFSObjectContentPath } from './gitLfsHelper'
import { buildIgnoreHelper } from './ignoreHelper'
import { Config } from '../types/config'

const FOLDER = 'tree'
Expand All @@ -21,9 +21,15 @@ const copiedFiles = new Set()
const writtenFiles = new Set()

export const copyFiles = async (config: Config, src: string) => {
if (copiedFiles.has(src) || writtenFiles.has(src)) return
if (copiedFiles.has(src) || writtenFiles.has(src)) {
return
}
copiedFiles.add(src)

const ignoreHelper = await buildIgnoreHelper(config)
if (ignoreHelper.globalIgnore.ignores(src)) {
return
}
try {
const bufferData: Buffer = await readPathFromGitAsBuffer(src, config)
const utf8Data = bufferData?.toString(UTF8_ENCODING) ?? ''
Expand Down Expand Up @@ -119,11 +125,18 @@ export async function* scan(
export const writeFile = async (
path: string,
content: string,
{ output }: Config
config: Config
) => {
if (writtenFiles.has(path)) return
if (writtenFiles.has(path)) {
return
}
writtenFiles.add(path)
await outputFile(join(output, treatPathSep(path)), content)

const ignoreHelper = await buildIgnoreHelper(config)
if (ignoreHelper.globalIgnore.ignores(path)) {
return
}
await outputFile(join(config.output, treatPathSep(path)), content)
}

export const isSubDir = (parent: string, dir: string) => {
Expand Down
8 changes: 2 additions & 6 deletions src/utils/ignoreHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class IgnoreHelper {
protected readonly destructiveIgnore: Ignore
) {}

public keep(line: string) {
public keep(line: string): boolean {
const changeType = line.charAt(0)

let ignInstance!: Ignore
Expand Down Expand Up @@ -47,7 +47,7 @@ export const buildIgnoreHelper = async ({
? await _buildIgnore(ignoreDestructive)
: await _buildIgnore(ignore)

await _addDefaultDestructiveIgnore(destructiveIgnore)
destructiveIgnore.add(BASE_DESTRUCTIVE_IGNORE)

ignoreInstance = new IgnoreHelper(globalIgnore, destructiveIgnore)
}
Expand Down Expand Up @@ -80,10 +80,6 @@ const _buildIgnore = async (ignorePath: string) => {
return ign
}

const _addDefaultDestructiveIgnore = async (destructiveIgnore: Ignore) => {
destructiveIgnore.add(BASE_DESTRUCTIVE_IGNORE)
}

export const resetIgnoreInstance = () => {
ignoreInstance = null
}
Expand Down
Loading