Skip to content

Commit

Permalink
[wrangler] Watch the entire module root + watch requirements.txt (#5310)
Browse files Browse the repository at this point in the history
  • Loading branch information
penalosa committed Mar 25, 2024
1 parent b1884c8 commit 528c011
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 51 deletions.
5 changes: 5 additions & 0 deletions .changeset/green-jokes-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler": minor
---

feat: Watch the entire module root for changes in `--no-bundle` mode, rather than just the entrypoint file.
5 changes: 5 additions & 0 deletions .changeset/thin-penguins-drum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler": patch
---

fix: Reload Python workers when the `requirements.txt` file changes
3 changes: 2 additions & 1 deletion packages/wrangler/e2e/deployments.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import crypto from "node:crypto";
import path from "node:path";
import shellac from "shellac";
import dedent from "ts-dedent";
import { fetch } from "undici";
import { beforeAll, describe, expect, it } from "vitest";
import { CLOUDFLARE_ACCOUNT_ID } from "./helpers/account-id";
import { normalizeOutput } from "./helpers/normalize";
import { retry } from "./helpers/retry";
import { dedent, makeRoot, seed } from "./helpers/setup";
import { makeRoot, seed } from "./helpers/setup";
import { WRANGLER } from "./helpers/wrangler-command";

function matchWorkersDev(stdout: string): string {
Expand Down
47 changes: 40 additions & 7 deletions packages/wrangler/e2e/dev.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import * as nodeNet from "node:net";
import path from "node:path";
import { setTimeout } from "node:timers/promises";
import shellac from "shellac";
import dedent from "ts-dedent";
import { Agent, fetch, setGlobalDispatcher } from "undici";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { normalizeOutput } from "./helpers/normalize";
import { retry } from "./helpers/retry";
import { dedent, makeRoot, seed } from "./helpers/setup";
import { makeRoot, seed } from "./helpers/setup";
import { WRANGLER } from "./helpers/wrangler-command";

// Use `Agent` with lower timeouts so `fetch()`s inside `retry()`s don't block for a long time
Expand Down Expand Up @@ -285,10 +286,15 @@ describe("basic dev python tests", () => {
compatibility_date = "2023-01-01"
compatibility_flags = ["python_workers"]
`,
"arithmetic.py": dedent`
def mul(a,b):
return a*b`,
"index.py": dedent`
from js import Response
def on_fetch(request):
return Response.new('py hello world')`,
from arithmetic import mul
from js import Response
def on_fetch(request):
return Response.new(f"py hello world {mul(2,3)}")`,
"package.json": dedent`
{
"name": "${workerName}",
Expand All @@ -299,7 +305,7 @@ describe("basic dev python tests", () => {
}));
});

it("can run and modify python worker during dev session (local)", async () => {
it("can run and modify python worker entrypoint during dev session (local)", async () => {
await worker.runDevSession("", async (session) => {
const { text } = await retry(
(s) => s.status !== 200,
Expand All @@ -308,7 +314,7 @@ describe("basic dev python tests", () => {
return { text: await r.text(), status: r.status };
}
);
expect(text).toMatchInlineSnapshot('"py hello world"');
expect(text).toMatchInlineSnapshot('"py hello world 6"');

await worker.seed({
"index.py": dedent`
Expand All @@ -318,7 +324,7 @@ describe("basic dev python tests", () => {
});

const { text: text2 } = await retry(
(s) => s.status !== 200 || s.text === "py hello world",
(s) => s.status !== 200 || s.text === "py hello world 6",
async () => {
const r = await fetch(`http://127.0.0.1:${session.port}`);
return { text: await r.text(), status: r.status };
Expand All @@ -327,6 +333,33 @@ describe("basic dev python tests", () => {
expect(text2).toMatchInlineSnapshot('"Updated Python Worker value"');
});
});
it("can run and modify python worker imports during dev session (local)", async () => {
await worker.runDevSession("", async (session) => {
const { text } = await retry(
(s) => s.status !== 200,
async () => {
const r = await fetch(`http://127.0.0.1:${session.port}`);
return { text: await r.text(), status: r.status };
}
);
expect(text).toMatchInlineSnapshot('"py hello world 6"');

await worker.seed({
"arithmetic.py": dedent`
def mul(a,b):
return a+b`,
});

const { text: text2 } = await retry(
(s) => s.status !== 200 || s.text === "py hello world 6",
async () => {
const r = await fetch(`http://127.0.0.1:${session.port}`);
return { text: await r.text(), status: r.status };
}
);
expect(text2).toMatchInlineSnapshot('"py hello world 5"');
});
});
});

describe("dev registry", () => {
Expand Down
38 changes: 0 additions & 38 deletions packages/wrangler/e2e/helpers/setup.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import assert from "node:assert";
import { mkdir, mkdtemp, writeFile } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
Expand All @@ -7,43 +6,6 @@ export async function makeRoot() {
return await mkdtemp(path.join(os.tmpdir(), "wrangler-smoke-"));
}

// Tagged template literal for removing indentation from a block of text.
// If the first line is empty, it will be ignored.
export function dedent(strings: TemplateStringsArray, ...values: unknown[]) {
// Convert template literal arguments back to a regular string
const raw = String.raw({ raw: strings }, ...values);
// Split the string by lines
let lines = raw.split("\n");
assert(lines.length > 0);

// If the last line is just whitespace, remove it
if (lines[lines.length - 1].trim() === "") {
lines = lines.slice(0, lines.length - 1);
}

// Find the minimum-length indent, excluding the first line
let minIndent = "";
// (Could use `minIndent.length` for this, but then would need to start with
// infinitely long string)
let minIndentLength = Infinity;
for (const line of lines.slice(1)) {
const indent = line.match(/^[ \t]*/)?.[0];
if (indent != null && indent.length < minIndentLength) {
minIndent = indent;
minIndentLength = indent.length;
}
}

// If the first line is just whitespace, remove it
if (lines.length > 0 && lines[0].trim() === "") lines = lines.slice(1);

// Remove indent from all lines, and return them all joined together
lines = lines.map((line) =>
line.startsWith(minIndent) ? line.substring(minIndent.length) : line
);
return lines.join("\n");
}

// Seeds the `root` directory on the file system with some data. Use in
// combination with `dedent` for petty formatting of seeded contents.
export async function seed(root: string, files: Record<string, string>) {
Expand Down
3 changes: 2 additions & 1 deletion packages/wrangler/e2e/pages-dev.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import path from "node:path";
import { setTimeout } from "node:timers/promises";
import getPort from "get-port";
import shellac from "shellac";
import dedent from "ts-dedent";
import { fetch } from "undici";
import { beforeEach, describe, expect, it } from "vitest";
import { normalizeOutput } from "./helpers/normalize";
import { retry } from "./helpers/retry";
import { dedent, makeRoot, seed } from "./helpers/setup";
import { makeRoot, seed } from "./helpers/setup";
import { WRANGLER } from "./helpers/wrangler-command";

type MaybePromise<T = void> = T | Promise<T>;
Expand Down
3 changes: 2 additions & 1 deletion packages/wrangler/e2e/versions.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import crypto from "node:crypto";
import path from "node:path";
import shellac from "shellac";
import dedent from "ts-dedent";
import { beforeAll, chai, describe, expect, it } from "vitest";
import { CLOUDFLARE_ACCOUNT_ID } from "./helpers/account-id";
import { normalizeOutput } from "./helpers/normalize";
import { dedent, makeRoot, seed } from "./helpers/setup";
import { makeRoot, seed } from "./helpers/setup";
import { WRANGLER } from "./helpers/wrangler-command";

chai.config.truncateThreshold = 1e6;
Expand Down
18 changes: 15 additions & 3 deletions packages/wrangler/src/dev/use-esbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,23 @@ export function useEsbuild({
// Capture the `stop()` method to use as the `useEffect()` destructor.
stopWatching = bundleResult?.stop;

// if "noBundle" is true, then we need to manually watch the entry point and
// trigger "builds" when it changes
// if "noBundle" is true, then we need to manually watch all modules and
// trigger "builds" when any change
if (noBundle) {
const watcher = watch(entry.file, {
const watching = [path.resolve(entry.moduleRoot)];
// Check whether we need to watch a Python requirements.txt file.
const watchPythonRequirements =
getBundleType(entry.format, entry.file) === "python"
? path.resolve(entry.directory, "requirements.txt")
: undefined;

if (watchPythonRequirements) {
watching.push(watchPythonRequirements);
}

const watcher = watch(watching, {
persistent: true,
ignored: [".git", "node_modules"],
}).on("change", async (_event) => {
await updateBundle();
});
Expand Down

0 comments on commit 528c011

Please sign in to comment.