Skip to content

Commit

Permalink
fix: create symlink parent directory before creating symlink itself (#…
Browse files Browse the repository at this point in the history
…1709)

* fix: don't swallow beginning of path

* chore: add repro

* fix: create link parent directory before creating link
  • Loading branch information
Skn0tt committed Feb 14, 2024
1 parent 9e82c5a commit db2f959
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 7 deletions.
15 changes: 11 additions & 4 deletions src/runtimes/node/utils/zip.ts
Expand Up @@ -2,7 +2,7 @@ import { Buffer } from 'buffer'
import { Stats } from 'fs'
import { mkdir, readlink as readLink, rm, symlink, writeFile } from 'fs/promises'
import os from 'os'
import { basename, extname, join } from 'path'
import { basename, extname, join, dirname } from 'path'

import { getPath as getV2APIPath } from '@netlify/serverless-functions-api'
import { copyFile } from 'cp-file'
Expand Down Expand Up @@ -154,9 +154,16 @@ const createDirectory = async function ({
{ concurrency: COPY_FILE_CONCURRENCY },
)

await pMap([...symlinks.entries()], ([target, path]) => symlink(target, path), {
concurrency: COPY_FILE_CONCURRENCY,
})
await pMap(
[...symlinks.entries()],
async ([target, path]) => {
await mkdir(dirname(path), { recursive: true })
await symlink(target, path)
},
{
concurrency: COPY_FILE_CONCURRENCY,
},
)

return { path: functionFolder, entryFilename }
}
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures-esm/symlinked-bin/function.ts
@@ -0,0 +1 @@
export default () => console.log('hello world')

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 38 additions & 3 deletions tests/symlinked_included_files.test.ts
Expand Up @@ -17,7 +17,7 @@ const readDirWithType = async (dir: string, readFiles?: Record<string, boolean>,

for (const dirent of dirents) {
if (dirent.isDirectory()) {
await readDirWithType(join(dir, dirent.name), files, dirent.name)
await readDirWithType(join(dir, dirent.name), files, join(parent, dirent.name))
} else {
files[join(parent, dirent.name)] = dirent.isSymbolicLink()
}
Expand All @@ -34,7 +34,7 @@ test.skipIf(platform() === 'win32')('Symlinked directories from `includedFiles`
// assert on the source files
expect(await readDirWithType(basePath)).toEqual({
'function.mjs': false,
[join('crazy-dep/package.json')]: false,
[join('node_modules/.pnpm/crazy-dep/package.json')]: false,
[join('node_modules/crazy-dep')]: true,
})

Expand Down Expand Up @@ -63,7 +63,42 @@ test.skipIf(platform() === 'win32')('Symlinked directories from `includedFiles`
'___netlify-bootstrap.mjs': false,
'___netlify-entry-point.mjs': false,
'function.mjs': false,
[join('crazy-dep/package.json')]: false,
[join('node_modules/.pnpm/crazy-dep/package.json')]: false,
[join('node_modules/crazy-dep')]: true,
})
})

test.skipIf(platform() === 'win32')('symlinks in subdir of `includedFiles` are copied over successfully', async () => {
const { path: tmpDir } = await getTmpDir({ prefix: 'zip-it-test' })
const basePath = join(FIXTURES_ESM_DIR, 'symlinked-bin')
const mainFile = join(basePath, 'function.ts')

// assert on the source files
expect(await readDirWithType(basePath)).toEqual({
'function.ts': false,
[join('subproject/node_modules/.bin/cli.js')]: true,
[join('subproject/node_modules/tool/cli.js')]: false,
})

await zipFunction(mainFile, tmpDir, {
archiveFormat: ARCHIVE_FORMAT.NONE,
basePath,
config: {
'*': {
includedFiles: ['subproject/**'],
},
},
repositoryRoot: basePath,
systemLog: console.log,
debug: true,
internalSrcFolder: undefined,
})

expect(await readDirWithType(join(tmpDir, 'function'))).toEqual({
'___netlify-bootstrap.mjs': false,
'___netlify-entry-point.mjs': false,
'function.cjs': false,
'subproject/node_modules/.bin/cli.js': true,
'subproject/node_modules/tool/cli.js': false,
})
})

1 comment on commit db2f959

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⏱ Benchmark results

  • largeDepsEsbuild: 1.5s
  • largeDepsNft: 5.5s
  • largeDepsZisi: 10.3s

Please sign in to comment.