Skip to content
This repository has been archived by the owner on May 22, 2024. It is now read-only.

fix: handle symlinks when creating directory #1640

Merged
merged 3 commits into from
Nov 2, 2023
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
25 changes: 23 additions & 2 deletions src/runtimes/node/utils/zip.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Buffer } from 'buffer'
import { Stats } from 'fs'
import { mkdir, rm, writeFile } from 'fs/promises'
import { mkdir, readlink as readLink, rm, symlink, writeFile } from 'fs/promises'
import os from 'os'
import { basename, extname, join } from 'path'

Expand Down Expand Up @@ -68,6 +68,7 @@ const addBootstrapFile = function (srcFiles: string[], aliases: Map<string, stri
const createDirectory = async function ({
aliases = new Map(),
basePath,
cache,
destFolder,
extension,
featureFlags,
Expand Down Expand Up @@ -116,10 +117,12 @@ const createDirectory = async function ({
addBootstrapFile(srcFiles, aliases)
}

const symlinks = new Map<string, string>()

// Copying source files.
await pMap(
srcFiles,
(srcFile) => {
async (srcFile) => {
const destPath = aliases.get(srcFile) || srcFile
const normalizedDestPath = normalizeFilePath({
commonPrefix: basePath,
Expand All @@ -132,11 +135,29 @@ const createDirectory = async function ({
return mkdirAndWriteFile(absoluteDestPath, rewrites.get(srcFile) as string)
}

const stat = await cachedLstat(cache.lstatCache, srcFile)

// If the path is a symlink, find the link target and add the link to a
// `symlinks` map, which we'll later use to create the symlinks in the
// target directory. We can't do that right now because the target path
// may not have been copied over yet.
if (stat.isSymbolicLink()) {
Copy link
Member Author

Choose a reason for hiding this comment

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

We should probably do the same in createZipArchive, but starting with createDirectory for now.

@ascorbic what happened when you tried to deploy the function to production?

Copy link
Member Author

Choose a reason for hiding this comment

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

According to the test, it works: 07061e0.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, it worked fine in builds

const targetPath = await readLink(srcFile)

symlinks.set(targetPath, absoluteDestPath)

return
}

return copyFile(srcFile, absoluteDestPath)
},
{ concurrency: COPY_FILE_CONCURRENCY },
)

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

return { path: functionFolder, entryFilename }
}

Expand Down
11 changes: 11 additions & 0 deletions tests/fixtures/pnpm-esm-v2/netlify/functions/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import filenamify from 'filenamify';

export default function handler(event, context) {
return new Response(filenamify('foo/bar'), {
headers: { 'content-type': 'text/plain' },
});
}

export const config = {
paths: "/api"
}
23 changes: 23 additions & 0 deletions tests/fixtures/pnpm-esm-v2/node_modules/.modules.yaml

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.

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.

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.

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.

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.

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.

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.

Loading