diff --git a/.changeset/cold-parrots-deliver.md b/.changeset/cold-parrots-deliver.md new file mode 100644 index 000000000000..fe9279aeef2f --- /dev/null +++ b/.changeset/cold-parrots-deliver.md @@ -0,0 +1,6 @@ +--- +"create-cloudflare": patch +"wrangler": patch +--- + +fix various logging of shell commands to correctly quote args when needed diff --git a/packages/create-cloudflare/src/cli.ts b/packages/create-cloudflare/src/cli.ts index bbd38825b337..bd94c5bb2953 100644 --- a/packages/create-cloudflare/src/cli.ts +++ b/packages/create-cloudflare/src/cli.ts @@ -8,6 +8,7 @@ import { detectPackageManager } from "helpers/packages"; import semver from "semver"; import { version } from "../package.json"; import { validateProjectDirectory } from "./common"; +import * as shellquote from "./helpers/shell-quote"; import { templateMap } from "./templateMap"; import type { C3Args } from "types"; @@ -55,7 +56,9 @@ export const runLatest = async () => { // the parsing logic of `npm create` requires `--` to be supplied // before any flags intended for the target command. const argString = - npm === "npm" ? `-- ${args.join(" ")}` : `${args.join(" ")}`; + npm === "npm" + ? `-- ${shellquote.quote(args)}` + : `${shellquote.quote(args)}`; await runCommand(`${npm} create cloudflare@latest ${argString}`); }; diff --git a/packages/create-cloudflare/src/helpers/shell-quote.ts b/packages/create-cloudflare/src/helpers/shell-quote.ts index 21ad74c95760..219ee85ce142 100644 --- a/packages/create-cloudflare/src/helpers/shell-quote.ts +++ b/packages/create-cloudflare/src/helpers/shell-quote.ts @@ -1,6 +1,10 @@ import shellquote from "shell-quote"; -export const quote = shellquote.quote; +export const quote = function (args: (string | number | boolean)[]) { + const stringArgs = args.map((arg) => String(arg)); + + return shellquote.quote(stringArgs); +}; export function parse(cmd: string, env?: Record): string[] { // This is a workaround for a bug in shell-quote on Windows diff --git a/packages/create-cloudflare/src/pages.ts b/packages/create-cloudflare/src/pages.ts index 2ddf5dbf461c..1f4df925f55c 100644 --- a/packages/create-cloudflare/src/pages.ts +++ b/packages/create-cloudflare/src/pages.ts @@ -19,6 +19,7 @@ import { runDeploy, setupProjectDirectory, } from "./common"; +import * as shellquote from "./helpers/shell-quote"; import type { C3Args, PagesGeneratorContext } from "types"; /** How many times to retry the create project command before failing. */ @@ -162,7 +163,9 @@ const createProject = async (ctx: PagesGeneratorContext) => { const CLOUDFLARE_ACCOUNT_ID = ctx.account.id; try { - const compatFlags = ctx.framework?.config.compatibilityFlags?.join(" "); + const compatFlags = shellquote.quote( + ctx.framework?.config.compatibilityFlags ?? [] + ); const compatFlagsArg = compatFlags ? `--compatibility-flags ${compatFlags}` : ""; diff --git a/packages/wrangler/src/__tests__/generate.test.ts b/packages/wrangler/src/__tests__/generate.test.ts index f5507b66ae04..d20ce4f7b685 100644 --- a/packages/wrangler/src/__tests__/generate.test.ts +++ b/packages/wrangler/src/__tests__/generate.test.ts @@ -43,7 +43,7 @@ describe("generate", () => { `"✨ Created no-template/wrangler.toml"` ); expect(std.warn).toMatchInlineSnapshot(` - "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 no-template\` instead. + "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 no-template\` instead. The \`init\` command will be removed in a future version. diff --git a/packages/wrangler/src/__tests__/init.test.ts b/packages/wrangler/src/__tests__/init.test.ts index 39ed41d2701d..326565e9409e 100644 --- a/packages/wrangler/src/__tests__/init.test.ts +++ b/packages/wrangler/src/__tests__/init.test.ts @@ -68,8 +68,8 @@ describe("init", () => { "debug": "", "err": "", "info": "", - "out": "Running \`mockpm create cloudflare@2\`...", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "out": "Running \`mockpm create cloudflare/@2\`...", + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -184,7 +184,7 @@ describe("init", () => { `); expect(std.err).toMatchInlineSnapshot(`""`); expect(std.warn).toMatchInlineSnapshot(` - "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 --wrangler-defaults\` instead. + "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 --wrangler-defaults\` instead. The \`init\` command will be removed in a future version. @@ -223,7 +223,7 @@ describe("init", () => { `); expect(std.err).toMatchInlineSnapshot(`""`); expect(std.warn).toMatchInlineSnapshot(` - "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 my-worker --wrangler-defaults\` instead. + "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 my-worker --wrangler-defaults\` instead. The \`init\` command will be removed in a future version. @@ -260,7 +260,7 @@ describe("init", () => { To start developing your Worker, run \`npm start\` To start testing your Worker, run \`npm test\` To publish your Worker to the Internet, run \`npm run deploy\`", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 --wrangler-defaults\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 --wrangler-defaults\` instead. The \`init\` command will be removed in a future version. @@ -340,7 +340,7 @@ describe("init", () => { "err": "", "info": "", "out": "✨ Created wrangler.toml", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -379,7 +379,7 @@ describe("init", () => { "err": "", "info": "", "out": "✨ Created my-worker/wrangler.toml", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 my-worker\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 my-worker\` instead. The \`init\` command will be removed in a future version. @@ -684,7 +684,7 @@ describe("init", () => { "info": "", "out": "✨ Created wrangler.toml ✨ Initialized git repository", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -729,7 +729,7 @@ describe("init", () => { To start developing your Worker, run \`npm start\` To start testing your Worker, run \`npm test\` To publish your Worker to the Internet, run \`npm run deploy\`", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 --wrangler-defaults\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 --wrangler-defaults\` instead. The \`init\` command will be removed in a future version. @@ -761,7 +761,7 @@ describe("init", () => { To start developing your Worker, run \`cd path/to/worker/my-worker && npm start\` To start testing your Worker, run \`npm test\` To publish your Worker to the Internet, run \`npm run deploy\`", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 path/to/worker/my-worker --wrangler-defaults\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 path/to/worker/my-worker --wrangler-defaults\` instead. The \`init\` command will be removed in a future version. @@ -794,7 +794,7 @@ describe("init", () => { "info": "", "out": "✨ Created wrangler.toml ✨ Initialized git repository", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -856,7 +856,7 @@ describe("init", () => { "info": "", "out": "✨ Created wrangler.toml ✨ Created package.json", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -912,7 +912,7 @@ describe("init", () => { "info": "", "out": "✨ Created my-worker/wrangler.toml ✨ Created my-worker/package.json", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 my-worker\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 my-worker\` instead. The \`init\` command will be removed in a future version. @@ -962,7 +962,7 @@ describe("init", () => { "err": "", "info": "", "out": "✨ Created wrangler.toml", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -1021,7 +1021,7 @@ describe("init", () => { "info": "", "out": "✨ Created path/to/worker/my-worker/wrangler.toml ✨ Created path/to/worker/my-worker/package.json", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 path/to/worker/my-worker\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 path/to/worker/my-worker\` instead. The \`init\` command will be removed in a future version. @@ -1079,7 +1079,7 @@ describe("init", () => { "info": "", "out": "✨ Created wrangler.toml ✨ Installed wrangler into devDependencies", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -1144,7 +1144,7 @@ describe("init", () => { "info": "", "out": "✨ Created wrangler.toml ✨ Installed wrangler into devDependencies", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -1204,7 +1204,7 @@ describe("init", () => { "err": "", "info": "", "out": "✨ Created wrangler.toml", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -1271,7 +1271,7 @@ describe("init", () => { To start developing your Worker, run \`npx wrangler dev\` To publish your Worker to the Internet, run \`npx wrangler deploy\`", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -1335,7 +1335,7 @@ describe("init", () => { To start developing your Worker, run \`npx wrangler dev\` To publish your Worker to the Internet, run \`npx wrangler deploy\`", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -1514,7 +1514,7 @@ describe("init", () => { "out": "✨ Created wrangler.toml ✨ Created tsconfig.json ✨ Installed @cloudflare/workers-types and typescript into devDependencies", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -1564,7 +1564,7 @@ describe("init", () => { ✨ Created my-worker/package.json ✨ Created my-worker/tsconfig.json ✨ Installed @cloudflare/workers-types and typescript into devDependencies", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 my-worker\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 my-worker\` instead. The \`init\` command will be removed in a future version. @@ -1625,7 +1625,7 @@ describe("init", () => { ✨ Created package.json ✨ Created tsconfig.json ✨ Installed @cloudflare/workers-types and typescript into devDependencies", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -1687,7 +1687,7 @@ describe("init", () => { To start developing your Worker, run \`npx wrangler dev\` To publish your Worker to the Internet, run \`npx wrangler deploy\`", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -1768,7 +1768,7 @@ describe("init", () => { To start developing your Worker, run \`cd path/to/worker/my-worker && npm start\` To start testing your Worker, run \`npm test\` To publish your Worker to the Internet, run \`npm run deploy\`", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 path/to/worker/my-worker\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 path/to/worker/my-worker\` instead. The \`init\` command will be removed in a future version. @@ -1830,7 +1830,7 @@ describe("init", () => { "out": "✨ Created wrangler.toml ✨ Installed @cloudflare/workers-types into devDependencies 🚨 Please add \\"@cloudflare/workers-types\\" to compilerOptions.types in tsconfig.json", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -1894,7 +1894,7 @@ describe("init", () => { To start developing your Worker, run \`npx wrangler dev\` To publish your Worker to the Internet, run \`npx wrangler deploy\`", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -1951,13 +1951,13 @@ describe("init", () => { }, }); expect(std.out).toMatchInlineSnapshot(` - "✨ Created wrangler.toml - ✨ Created package.json - ✨ Created src/index.js + "✨ Created wrangler.toml + ✨ Created package.json + ✨ Created src/index.js - To start developing your Worker, run \`npm start\` - To publish your Worker to the Internet, run \`npm run deploy\`" - `); + To start developing your Worker, run \`npm start\` + To publish your Worker to the Internet, run \`npm run deploy\`" + `); }); it("should add a jest test for a non-ts project with .js extension", async () => { mockConfirm( @@ -2141,12 +2141,12 @@ describe("init", () => { }, }); expect(std.out).toMatchInlineSnapshot(` - "✨ Created wrangler.toml - ✨ Created src/index.js + "✨ Created wrangler.toml + ✨ Created src/index.js - To start developing your Worker, run \`npx wrangler dev\` - To publish your Worker to the Internet, run \`npx wrangler deploy\`" - `); + To start developing your Worker, run \`npx wrangler dev\` + To publish your Worker to the Internet, run \`npx wrangler deploy\`" + `); }); it("should not offer to create a worker in a non-ts project if a file already exists at the location", async () => { @@ -2186,7 +2186,7 @@ describe("init", () => { "err": "", "info": "", "out": "✨ Created wrangler.toml", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2\` instead. The \`init\` command will be removed in a future version. @@ -2237,7 +2237,7 @@ describe("init", () => { "err": "", "info": "", "out": "✨ Created my-worker/wrangler.toml", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 my-worker\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 my-worker\` instead. The \`init\` command will be removed in a future version. @@ -2303,7 +2303,7 @@ describe("init", () => { To start developing your Worker, run \`npm start\` To start testing your Worker, run \`npm test\` To publish your Worker to the Internet, run \`npm run deploy\`", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 . --wrangler-defaults\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 . --wrangler-defaults\` instead. The \`init\` command will be removed in a future version. @@ -2339,7 +2339,7 @@ describe("init", () => { To start developing your Worker, run \`cd path/to/worker && npm start\` To start testing your Worker, run \`npm test\` To publish your Worker to the Internet, run \`npm run deploy\`", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 path/to/worker --wrangler-defaults\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 path/to/worker --wrangler-defaults\` instead. The \`init\` command will be removed in a future version. @@ -2377,7 +2377,7 @@ describe("init", () => { To start developing your Worker, run \`cd WEIRD_w0rkr_N4m3.js.tsx.tar.gz && npm start\` To start testing your Worker, run \`npm test\` To publish your Worker to the Internet, run \`npm run deploy\`", - "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare@2 WEIRD_w0rkr_N4m3.js.tsx.tar.gz --wrangler-defaults\` instead. + "warn": "▲ [WARNING] The \`init\` command is no longer supported. Please use \`mockpm create cloudflare/@2 WEIRD_w0rkr_N4m3.js.tsx.tar.gz --wrangler-defaults\` instead. The \`init\` command will be removed in a future version. diff --git a/packages/wrangler/src/init.ts b/packages/wrangler/src/init.ts index 2ff4d1540d38..aa310335a979 100644 --- a/packages/wrangler/src/init.ts +++ b/packages/wrangler/src/init.ts @@ -256,8 +256,8 @@ export async function initHandler(args: InitArgs) { c3Arguments.unshift(...shellquote.parse(getC3CommandFromEnv())); // Deprecate the `init --from-dash` command - const replacementC3Command = `\`${packageManager.type} ${c3Arguments.join( - " " + const replacementC3Command = `\`${packageManager.type} ${shellquote.quote( + c3Arguments )}\``; logger.warn( diff --git a/packages/wrangler/src/pages/dev.ts b/packages/wrangler/src/pages/dev.ts index c5500983dc4f..478b5296319a 100644 --- a/packages/wrangler/src/pages/dev.ts +++ b/packages/wrangler/src/pages/dev.ts @@ -11,6 +11,7 @@ import { FatalError } from "../errors"; import { logger } from "../logger"; import * as metrics from "../metrics"; import { getBasePath } from "../paths"; +import * as shellquote from "../utils/shell-quote"; import { buildFunctions } from "./buildFunctions"; import { ROUTES_SPEC_VERSION, SECONDS_TO_WAIT_FOR_PROXY } from "./constants"; import { @@ -797,7 +798,7 @@ async function spawnProxyProcess({ ); } - logger.log(`Running ${command.join(" ")}...`); + logger.log(`Running ${shellquote.quote(command)}...`); const proxy = spawn( command[0].toString(), command.slice(1).map((value) => value.toString()), diff --git a/packages/wrangler/src/utils/shell-quote.ts b/packages/wrangler/src/utils/shell-quote.ts index 21ad74c95760..219ee85ce142 100644 --- a/packages/wrangler/src/utils/shell-quote.ts +++ b/packages/wrangler/src/utils/shell-quote.ts @@ -1,6 +1,10 @@ import shellquote from "shell-quote"; -export const quote = shellquote.quote; +export const quote = function (args: (string | number | boolean)[]) { + const stringArgs = args.map((arg) => String(arg)); + + return shellquote.quote(stringArgs); +}; export function parse(cmd: string, env?: Record): string[] { // This is a workaround for a bug in shell-quote on Windows