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: skip unwanted files and directories when publishing site assets #280

Merged
merged 1 commit into from
Jan 24, 2022
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
11 changes: 11 additions & 0 deletions .changeset/violet-wasps-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"wrangler": patch
---

fix: skip unwanted files and directories when publishing site assets

In keeping with Wrangler 1, we now skip node_modules and hidden files and directories.

An exception is made for `.well-known`. See https://datatracker.ietf.org/doc/html/rfc8615.

The tests also prove that the asset uploader will walk directories in general.
88 changes: 88 additions & 0 deletions packages/wrangler/src/__tests__/publish.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,94 @@ describe("publish", () => {
expect(error).toMatchInlineSnapshot(`undefined`);
});

it("should walk directories except node_modules", async () => {
const assets = [
{
filePath: "assets/directory-1/file-1.txt",
content: "Content of file-1",
},
{
filePath: "assets/node_modules/file-2.txt",
content: "Content of file-2",
},
];
const kvNamespace = {
title: "__test-name_sites_assets",
id: "__test-name_sites_assets-id",
};
writeWranglerToml("./index.js", "assets");
writeEsmWorkerSource();
writeAssets(assets);
mockUploadWorkerRequest();
mockSubDomainRequest();
mockListKVNamespacesRequest(kvNamespace);
mockKeyListRequest(kvNamespace.id, []);
// Only expect file-1 to be uploaded
mockUploadAssetsToKVRequest(kvNamespace.id, assets.slice(0, 1));
const { stdout, stderr, error } = await runWrangler("publish");

expect(stripTimings(stdout)).toMatchInlineSnapshot(`
"reading assets/directory-1/file-1.txt...
uploading as assets/directory-1/file-1.2ca234f380.txt...
Uploaded
test-name
(TIMINGS)
Deployed
test-name
(TIMINGS)

test-name.test-sub-domain.workers.dev"
`);
expect(stderr).toMatchInlineSnapshot(`""`);
expect(error).toMatchInlineSnapshot(`undefined`);
});

it("should skip hidden files and directories except `.well-known`", async () => {
const assets = [
{
filePath: "assets/.hidden-file.txt",
content: "Content of hidden-file",
},
{
filePath: "assets/.hidden/file-1.txt",
content: "Content of file-1",
},
{
filePath: "assets/.well-known/file-2.txt",
content: "Content of file-2",
},
];
const kvNamespace = {
title: "__test-name_sites_assets",
id: "__test-name_sites_assets-id",
};
writeWranglerToml("./index.js", "assets");
writeEsmWorkerSource();
writeAssets(assets);
mockUploadWorkerRequest();
mockSubDomainRequest();
mockListKVNamespacesRequest(kvNamespace);
mockKeyListRequest(kvNamespace.id, []);
// Only expect file-2 to be uploaded
mockUploadAssetsToKVRequest(kvNamespace.id, assets.slice(2));
const { stdout, stderr, error } = await runWrangler("publish");

expect(stripTimings(stdout)).toMatchInlineSnapshot(`
"reading assets/.well-known/file-2.txt...
uploading as assets/.well-known/file-2.5938485188.txt...
Uploaded
test-name
(TIMINGS)
Deployed
test-name
(TIMINGS)

test-name.test-sub-domain.workers.dev"
`);
expect(stderr).toMatchInlineSnapshot(`""`);
expect(error).toMatchInlineSnapshot(`undefined`);
});

it("should error if the asset is over 25Mb", async () => {
const assets = [
{
Expand Down
19 changes: 17 additions & 2 deletions packages/wrangler/src/sites.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,26 @@ import { fetchResult } from "./cfetch";
import type { Config } from "./config";
import { listNamespaceKeys, listNamespaces, putBulkKeyValue } from "./kv";

/** Paths to always ignore. */
const ALWAYS_IGNORE = ["node_modules"];
const HIDDEN_FILES_TO_INCLUDE = [
".well-known", // See https://datatracker.ietf.org/doc/html/rfc8615
];

async function* getFilesInFolder(dirPath: string): AsyncIterable<string> {
const files = await readdir(dirPath, { withFileTypes: true });
for (const file of files) {
// TODO: always ignore `node_modules`
// TODO: ignore hidden files (starting with .) but not .well-known??
// Skip files that we never want to process.
if (ALWAYS_IGNORE.some((p) => file.name === p)) {
continue;
}
// Skip hidden files (starting with .) except for some special ones
if (
file.name.startsWith(".") &&
!HIDDEN_FILES_TO_INCLUDE.some((p) => file.name === p)
) {
continue;
}
// TODO: follow symlinks??
if (file.isDirectory()) {
yield* await getFilesInFolder(path.join(dirPath, file.name));
Expand Down