Skip to content

Commit

Permalink
Feat(unstable_dev): Don't fetch from npm on boot (#4347)
Browse files Browse the repository at this point in the history
  • Loading branch information
Skye-31 authored Nov 7, 2023
1 parent a441102 commit 102e15f
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 42 deletions.
5 changes: 5 additions & 0 deletions .changeset/cyan-books-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler": minor
---

Feat(unstable_dev): Provide an option for unstable_dev to perform the check that prompts users to update wrangler, defaulting to false. This will prevent unstable_dev from sending a request to NPM on startup to determine whether it needs to be updated.
40 changes: 40 additions & 0 deletions packages/wrangler/src/__tests__/api-dev.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as fs from "node:fs";
import { Request } from "undici";
import { unstable_dev } from "../api";
import { printWranglerBanner } from "../update-check";
import { runInTempDir } from "./helpers/run-in-tmp";

jest.unmock("child_process");
Expand Down Expand Up @@ -52,6 +53,45 @@ describe("unstable_dev", () => {
expect(worker.port).not.toBe(0);
await worker.stop();
});

describe("unstable_dev network calls", () => {
it("should not make a request to NPM without `updateCheck` being true", async () => {
const worker = await unstable_dev(
"src/__tests__/helpers/worker-scripts/hello-world-worker.js",
{
experimental: {
disableExperimentalWarning: true,
disableDevRegistry: true,
},
}
);
const resp = await worker.fetch();
expect(resp.status).toBe(200);

expect((printWranglerBanner as jest.Mock).mock.calls[0][0]).toBe(false);

await worker.stop();
});

it("should make a request to NPM when `updateCheck` is true", async () => {
const worker = await unstable_dev(
"src/__tests__/helpers/worker-scripts/hello-world-worker.js",
{
experimental: {
disableExperimentalWarning: true,
disableDevRegistry: true,
},
updateCheck: true,
}
);
const resp = await worker.fetch();
expect(resp.status).toBe(200);

expect((printWranglerBanner as jest.Mock).mock.calls[0][0]).toBe(true);

await worker.stop();
});
});
});

describe("unstable dev fetch input protocol", () => {
Expand Down
2 changes: 2 additions & 0 deletions packages/wrangler/src/__tests__/jest.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ fetchMock.doMock(() => {

jest.mock("../package-manager");

jest.mock("../update-check");

// requests not mocked with `jest-fetch-mock` fall through
// to `mock-service-worker`
fetchMock.dontMock();
Expand Down
6 changes: 4 additions & 2 deletions packages/wrangler/src/api/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export interface UnstableDevOptions {
inspect?: boolean;
local?: boolean;
accountId?: string;
updateCheck?: boolean;
experimental?: {
processEntrypoint?: boolean;
additionalModules?: CfModule[];
Expand Down Expand Up @@ -139,10 +140,8 @@ export async function unstable_dev(
const devOptions: StartDevOptions = {
script: script,
inspect: false,
logLevel: options?.logLevel ?? defaultLogLevel,
_: [],
$0: "",
port: options?.port ?? 0,
remote: !local,
local,
experimentalLocal: undefined,
Expand Down Expand Up @@ -194,6 +193,9 @@ export async function unstable_dev(
legacyEnv: undefined,
public: undefined,
...options,
logLevel: options?.logLevel ?? defaultLogLevel,
port: options?.port ?? 0,
updateCheck: options?.updateCheck ?? false,
};

//due to Pages adoption of unstable_dev, we can't *just* disable rebuilds and watching. instead, we'll have two versions of startDev, which will converge.
Expand Down
5 changes: 3 additions & 2 deletions packages/wrangler/src/dev.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ export type StartDevOptions = DevArguments &
enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
onReady?: (ip: string, port: number) => void;
showInteractiveDevSession?: boolean;
updateCheck?: boolean;
};

export async function startDev(args: StartDevOptions) {
Expand All @@ -351,7 +352,7 @@ export async function startDev(args: StartDevOptions) {
if (args.logLevel) {
logger.loggerLevel = args.logLevel;
}
await printWranglerBanner();
await printWranglerBanner(args.updateCheck);
if (args.local) {
logger.warn(
"--local is no longer required and will be removed in a future version.\n`wrangler dev` now uses the local Cloudflare Workers runtime by default. 🎉"
Expand Down Expand Up @@ -518,7 +519,7 @@ export async function startApiDev(args: StartDevOptions) {
if (args.logLevel) {
logger.loggerLevel = args.logLevel;
}
await printWranglerBanner();
await printWranglerBanner(args.updateCheck);

const configPath =
args.config || (args.script && findWranglerToml(path.dirname(args.script)));
Expand Down
41 changes: 3 additions & 38 deletions packages/wrangler/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import module from "node:module";
import os from "node:os";
import TOML from "@iarna/toml";
import chalk from "chalk";
import supportsColor from "supports-color";
import { ProxyAgent, setGlobalDispatcher } from "undici";
import makeCLI from "yargs";
import { version as wranglerVersion } from "../package.json";
Expand Down Expand Up @@ -50,7 +48,7 @@ import { r2 } from "./r2";
import { secret, secretBulkHandler, secretBulkOptions } from "./secret";
import { tailOptions, tailHandler } from "./tail";
import { generateTypes } from "./type-generation";
import { updateCheck } from "./update-check";
import { printWranglerBanner } from "./update-check";
import { listScopes, login, logout, validateScopeKeys } from "./user";
import { vectorize } from "./vectorize/index";
import { whoami } from "./whoami";
Expand Down Expand Up @@ -97,41 +95,6 @@ ${TOML.stringify({ rules: config.build.upload.rules })}`
return rules;
}

export async function printWranglerBanner() {
// Let's not print this in tests
if (typeof jest !== "undefined") {
return;
}

let text = ` ⛅️ wrangler ${wranglerVersion}`;
const maybeNewVersion = await updateCheck();
if (maybeNewVersion !== undefined) {
text += ` (update available ${chalk.green(maybeNewVersion)})`;
}

logger.log(
text +
"\n" +
(supportsColor.stdout
? chalk.hex("#FF8800")("-".repeat(text.length))
: "-".repeat(text.length))
);

// Log a slightly more noticeable message if this is a major bump
if (maybeNewVersion !== undefined) {
const currentMajor = parseInt(wranglerVersion.split(".")[0]);
const newMajor = parseInt(maybeNewVersion.split(".")[0]);
if (newMajor > currentMajor) {
logger.warn(
`The version of Wrangler you are using is now out-of-date.
Please update to the latest version to prevent critical errors.
Run \`npm install --save-dev wrangler@${newMajor}\` to update to the latest version.
After installation, run Wrangler with \`npx wrangler\`.`
);
}
}
}

export function isLegacyEnv(config: Config): boolean {
// We only read from config here, because we've already accounted for
// args["legacy-env"] in https://github.com/cloudflare/workers-sdk/blob/b24aeb5722370c2e04bce97a84a1fa1e55725d79/packages/wrangler/src/config/validation.ts#L94-L98
Expand Down Expand Up @@ -832,3 +795,5 @@ export function getDevCompatibilityDate(
}
return compatibilityDate ?? currentDate;
}

export { printWranglerBanner };
1 change: 1 addition & 0 deletions packages/wrangler/src/pages/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,7 @@ export const Handler = async ({
persistTo,
inspect: undefined,
logLevel,
updateCheck: true,
experimental: {
processEntrypoint: true,
additionalModules: modules,
Expand Down
37 changes: 37 additions & 0 deletions packages/wrangler/src/update-check.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,44 @@
import chalk from "chalk";
import supportsColor from "supports-color";
import checkForUpdate from "update-check";
import pkg from "../package.json";
import { version as wranglerVersion } from "../package.json";
import { logger } from "./logger";
import type { Result } from "update-check";

export async function printWranglerBanner(performUpdateCheck = true) {
let text = ` ⛅️ wrangler ${wranglerVersion}`;
let maybeNewVersion: string | undefined;
if (performUpdateCheck) {
maybeNewVersion = await updateCheck();
if (maybeNewVersion !== undefined) {
text += ` (update available ${chalk.green(maybeNewVersion)})`;
}
}

logger.log(
text +
"\n" +
(supportsColor.stdout
? chalk.hex("#FF8800")("-".repeat(text.length))
: "-".repeat(text.length))
);

// Log a slightly more noticeable message if this is a major bump
if (maybeNewVersion !== undefined) {
const currentMajor = parseInt(wranglerVersion.split(".")[0]);
const newMajor = parseInt(maybeNewVersion.split(".")[0]);
if (newMajor > currentMajor) {
logger.warn(
`The version of Wrangler you are using is now out-of-date.
Please update to the latest version to prevent critical errors.
Run \`npm install --save-dev wrangler@${newMajor}\` to update to the latest version.
After installation, run Wrangler with \`npx wrangler\`.`
);
}
}
}

async function doUpdateCheck(): Promise<string | undefined> {
let update: Result | null = null;
try {
Expand Down

0 comments on commit 102e15f

Please sign in to comment.