Skip to content

Commit

Permalink
fix(copy): more straightforward and reliable way to prevent copy over…
Browse files Browse the repository at this point in the history
…writing
  • Loading branch information
jeremyben committed May 30, 2020
1 parent 3d61f4b commit 1cd622f
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 25 deletions.
4 changes: 2 additions & 2 deletions __tests__/copy-addon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ afterEach(() => {
describe('Copy addon', () => {
test('all other files', () => {
const expectedOtherFiles = readdirSync(join(basePath, 'src', 'other'))
const consoleInfoSpy = spyOn(console, 'info')
const consoleWarnSpy = spyOn(console, 'warn')

build({
basePath,
Expand All @@ -28,7 +28,7 @@ describe('Copy addon', () => {
const excludedDirDistPath = join(basePath, 'dist', 'excluded')
expect(existsSync(excludedDirDistPath)).toBe(false)

expect(consoleInfoSpy).toHaveBeenCalledWith(expect.stringMatching(/override.*main\.js/))
expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringMatching(/already.*main\.js/))
})

test('do not recursively copy outDir to outDir', () => {
Expand Down
4 changes: 2 additions & 2 deletions src/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ export function createProgramFromConfig({
host,
})

// @ts-ignore https://github.com/Microsoft/TypeScript/issues/1863
program[excludeKey] = config.exclude
// https://github.com/Microsoft/TypeScript/issues/1863
;(program as any)[excludeKey] = config.exclude

return program
}
Expand Down
27 changes: 9 additions & 18 deletions src/copy-addon.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ts from 'typescript'
import { relativeToCWD, changeDir, changeExtension } from './utils/path'
import { changeDir } from './utils/path'
import { cp } from './utils/fs'
import { Color } from './utils/log'

/**
* Copy non-typescript files to `outDir`.
Expand All @@ -13,17 +14,8 @@ export default function copyOtherFiles(program: ts.Program) {
const outDir = options.outDir! // already checked before
const declarationDir = options.declarationDir

// Retrieve a list of emitted .js files included in the program, by manipulating paths.
// We could have retrieved them by changing the original `listEmittedFiles` option,
// but we would have had to create another intermediary program and handle more complexity.
const emittedFiles = program.getRootFileNames().map((srcFile) => {
let destFile = changeDir(srcFile, srcDir, outDir)
destFile = changeExtension(destFile, ['.ts'], '.js')
return destFile
})

// @ts-ignore https://github.com/Microsoft/TypeScript/issues/1863
const excludes: string[] = program[excludeKey] || []
// https://github.com/Microsoft/TypeScript/issues/1863
const excludes: string[] = (program as any)[excludeKey] || []
// Exclude typescript files and outDir/declarationDir if previously emitted in the same folder
excludes.push('**/*.ts', outDir, declarationDir || '')
const otherFiles = matchAllFilesBut(srcDir, excludes)
Expand All @@ -34,14 +26,13 @@ export default function copyOtherFiles(program: ts.Program) {
for (const srcOtherFile of otherFiles) {
const destOtherFile = changeDir(srcOtherFile, srcDir, outDir)

// Avoid overwriting precedently emitted js files
const alreadyEmitted = emittedFiles.some((emittedFile) => emittedFile === destOtherFile)
if (alreadyEmitted) {
console.info(`Won't override previously emitted file: ${relativeToCWD(destOtherFile)}`)
continue
try {
cp(srcOtherFile, destOtherFile)
} catch (error) {
if (error.code === 'EEXIST') console.warn(Color.yellow(error.message))
else throw error
}

cp(srcOtherFile, destOtherFile, !alreadyEmitted)
copiedFiles.push(destOtherFile)
}

Expand Down
5 changes: 2 additions & 3 deletions src/utils/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import { relativeToCWD } from './path'
* Copy file, create parent folders if necessary.
* @internal
*/
export function cp(srcFilePath: string, destFilePath: string, force = true) {
const copyFlag = force ? 0 : fs.constants.COPYFILE_EXCL
export function cp(srcFilePath: string, destFilePath: string, overwrite = false) {
const parentDir = dirname(destFilePath)
fs.mkdirSync(parentDir, { recursive: true }) // no EEXIST error issue with recursive option
fs.copyFileSync(srcFilePath, destFilePath, copyFlag)
fs.copyFileSync(srcFilePath, destFilePath, overwrite ? 0 : fs.constants.COPYFILE_EXCL)
}

/**
Expand Down

0 comments on commit 1cd622f

Please sign in to comment.