From fd55a71ebfc629da0e685c38edee70db8798950a Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Fri, 25 Oct 2024 18:37:57 +0900 Subject: [PATCH 1/4] fix upgrade --- src/args.ts | 1 + src/subcommands/upgrade.ts | 39 ++++++++++-------- tests/upgrade_test.ts | 81 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 16 deletions(-) create mode 100644 tests/upgrade_test.ts diff --git a/src/args.ts b/src/args.ts index 90b40a0..08492a6 100644 --- a/src/args.ts +++ b/src/args.ts @@ -47,6 +47,7 @@ export function parseArgs(args: string[]) { "db", "env", "env-file", + "root", ], collect: [ "grep", diff --git a/src/subcommands/upgrade.ts b/src/subcommands/upgrade.ts index 81788c2..ce8a5bc 100644 --- a/src/subcommands/upgrade.ts +++ b/src/subcommands/upgrade.ts @@ -7,6 +7,7 @@ import { parse as semverParse, } from "@std/semver"; import { VERSION } from "../version.ts"; +import type { Args as RawArgs } from "../args.ts"; const help = `deployctl upgrade Upgrade deployctl to the given version (defaults to latest). @@ -29,24 +30,33 @@ ARGS: The version to upgrade to (defaults to latest) `; -export interface Args { +type UpgradeArgs = { help: boolean; -} + /** + * If present, this value will be provided to `deno install` command that the + * upgrade subcommand internally invokes. This option is not documented in the + * help message as its intended use is for testing. + */ + root: string | null; +}; -// deno-lint-ignore no-explicit-any -export default async function (rawArgs: Record): Promise { - const args: Args = { +export default async function (rawArgs: RawArgs): Promise { + const version = typeof rawArgs._[0] === "string" ? rawArgs._[0] : null; + const args: UpgradeArgs = { help: !!rawArgs.help, + root: rawArgs.root ?? null, }; - const version = typeof rawArgs._[0] === "string" ? rawArgs._[0] : null; + if (args.help) { console.log(help); - Deno.exit(); + Deno.exit(0); } + if (rawArgs._.length > 1) { console.error(help); error("Too many positional arguments given."); } + if (version && !semverValid(version)) { error(`The provided version is invalid.`); } @@ -70,17 +80,14 @@ export default async function (rawArgs: Record): Promise { const process = new Deno.Command(Deno.execPath(), { args: [ "install", - "--allow-read", - "--allow-write", - "--allow-env", - "--allow-net", - "--allow-run", - "--allow-sys", - "--no-check", + "-A", + "--global", + args.root ? `--root=${args.root}` : undefined, + "--reload", "--force", "--quiet", - `https://deno.land/x/deploy@${version ? version : latest}/deployctl.ts`, - ], + `jsr:@deno/deployctl@${version || latest}`, + ].filter((x) => x !== undefined), }).spawn(); await process.status; } diff --git a/tests/upgrade_test.ts b/tests/upgrade_test.ts new file mode 100644 index 0000000..3205099 --- /dev/null +++ b/tests/upgrade_test.ts @@ -0,0 +1,81 @@ +import { assert } from "@std/assert/assert"; +import { assertEquals } from "@std/assert/assert_equals"; +import { join } from "@std/path/join"; +import { VERSION } from "../src/version.ts"; + +// Install the current script, then upgrade it to 1.12.0 (effectively downgrade) +// to see if the upgrade command works as expected. +Deno.test("upgrade", async () => { + const decoder = new TextDecoder(); + + const tempDir = await Deno.makeTempDir(); + console.log(tempDir); + + // Install the current `deployctl.ts` + { + const installCmd = await new Deno.Command(Deno.execPath(), { + args: [ + "install", + "-A", + "--reload", + "--force", + "--global", + "--config", + join(Deno.cwd(), "deno.jsonc"), + "--root", + tempDir, + join(Deno.cwd(), "deployctl.ts"), + ], + stdout: "inherit", + stderr: "inherit", + }).output(); + assert(installCmd.success); + } + + // Check the version of the installed `deployctl` + { + const versionCmd = await new Deno.Command(`${tempDir}/bin/deployctl`, { + args: ["--version"], + }).output(); + const stdout = decoder.decode(versionCmd.stdout).trim(); + const stderr = decoder.decode(versionCmd.stderr).trim(); + assert(versionCmd.success, `stdout: ${stdout}\nstderr: ${stderr}`); + assertEquals( + stdout, + `deployctl ${VERSION}`, + `stdout: ${stdout}\nstderr: ${stderr}`, + ); + } + + const UPGRADE_VERSION = "1.12.0"; + + // "Upgrade" the installed `deployctl` to 1.12.0 + { + const upgradeCmd = await new Deno.Command(`${tempDir}/bin/deployctl`, { + args: [ + "upgrade", + "--root", + tempDir, + UPGRADE_VERSION, + ], + stdout: "inherit", + stderr: "inherit", + }).output(); + assert(upgradeCmd.success); + } + + // Check the version of the "upgraded" `deployctl` + { + const versionCmd = await new Deno.Command(`${tempDir}/bin/deployctl`, { + args: ["--version"], + }).output(); + const stdout = decoder.decode(versionCmd.stdout).trim(); + const stderr = decoder.decode(versionCmd.stderr).trim(); + assert(versionCmd.success); + assertEquals( + stdout, + `deployctl ${UPGRADE_VERSION}`, + `stdout: ${stdout}\nstderr: ${stderr}`, + ); + } +}); From 2b6e453d04cb22ad840ba85f3df60533e33553cf Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Fri, 25 Oct 2024 18:49:27 +0900 Subject: [PATCH 2/4] add upgrade section to readme --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 66847b2..cf338a9 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,20 @@ You need to have Deno 1.46.0+ installed (latest version is recommended; just run deno install -gArf jsr:@deno/deployctl ``` +## Upgrade + +If you have `deployctl` already installed, you can upgrade to the latest version +by running: + +```shell +deployctl upgrade +``` + +> [!WARNING] +> If your `deployctl` is older than 1.13.0 and you are using Deno v2.x, +> `deployctl upgrade` does not work. You instead need to run +> `deno install -gArf jsr:@deno/deployctl` in this case. + ## Usage The easiest way to get started with `deployctl` is to deploy one of the examples From 5af23713b09aab22873a6495b4674596a989a921 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Fri, 25 Oct 2024 18:51:40 +0900 Subject: [PATCH 3/4] fmt --- tests/upgrade_test.ts | 132 +++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/tests/upgrade_test.ts b/tests/upgrade_test.ts index 3205099..577cbc2 100644 --- a/tests/upgrade_test.ts +++ b/tests/upgrade_test.ts @@ -6,76 +6,76 @@ import { VERSION } from "../src/version.ts"; // Install the current script, then upgrade it to 1.12.0 (effectively downgrade) // to see if the upgrade command works as expected. Deno.test("upgrade", async () => { - const decoder = new TextDecoder(); + const decoder = new TextDecoder(); - const tempDir = await Deno.makeTempDir(); - console.log(tempDir); + const tempDir = await Deno.makeTempDir(); + console.log(tempDir); - // Install the current `deployctl.ts` - { - const installCmd = await new Deno.Command(Deno.execPath(), { - args: [ - "install", - "-A", - "--reload", - "--force", - "--global", - "--config", - join(Deno.cwd(), "deno.jsonc"), - "--root", - tempDir, - join(Deno.cwd(), "deployctl.ts"), - ], - stdout: "inherit", - stderr: "inherit", - }).output(); - assert(installCmd.success); - } + // Install the current `deployctl.ts` + { + const installCmd = await new Deno.Command(Deno.execPath(), { + args: [ + "install", + "-A", + "--reload", + "--force", + "--global", + "--config", + join(Deno.cwd(), "deno.jsonc"), + "--root", + tempDir, + join(Deno.cwd(), "deployctl.ts"), + ], + stdout: "inherit", + stderr: "inherit", + }).output(); + assert(installCmd.success); + } - // Check the version of the installed `deployctl` - { - const versionCmd = await new Deno.Command(`${tempDir}/bin/deployctl`, { - args: ["--version"], - }).output(); - const stdout = decoder.decode(versionCmd.stdout).trim(); - const stderr = decoder.decode(versionCmd.stderr).trim(); - assert(versionCmd.success, `stdout: ${stdout}\nstderr: ${stderr}`); - assertEquals( - stdout, - `deployctl ${VERSION}`, - `stdout: ${stdout}\nstderr: ${stderr}`, - ); - } + // Check the version of the installed `deployctl` + { + const versionCmd = await new Deno.Command(`${tempDir}/bin/deployctl`, { + args: ["--version"], + }).output(); + const stdout = decoder.decode(versionCmd.stdout).trim(); + const stderr = decoder.decode(versionCmd.stderr).trim(); + assert(versionCmd.success, `stdout: ${stdout}\nstderr: ${stderr}`); + assertEquals( + stdout, + `deployctl ${VERSION}`, + `stdout: ${stdout}\nstderr: ${stderr}`, + ); + } - const UPGRADE_VERSION = "1.12.0"; + const UPGRADE_VERSION = "1.12.0"; - // "Upgrade" the installed `deployctl` to 1.12.0 - { - const upgradeCmd = await new Deno.Command(`${tempDir}/bin/deployctl`, { - args: [ - "upgrade", - "--root", - tempDir, - UPGRADE_VERSION, - ], - stdout: "inherit", - stderr: "inherit", - }).output(); - assert(upgradeCmd.success); - } + // "Upgrade" the installed `deployctl` to 1.12.0 + { + const upgradeCmd = await new Deno.Command(`${tempDir}/bin/deployctl`, { + args: [ + "upgrade", + "--root", + tempDir, + UPGRADE_VERSION, + ], + stdout: "inherit", + stderr: "inherit", + }).output(); + assert(upgradeCmd.success); + } - // Check the version of the "upgraded" `deployctl` - { - const versionCmd = await new Deno.Command(`${tempDir}/bin/deployctl`, { - args: ["--version"], - }).output(); - const stdout = decoder.decode(versionCmd.stdout).trim(); - const stderr = decoder.decode(versionCmd.stderr).trim(); - assert(versionCmd.success); - assertEquals( - stdout, - `deployctl ${UPGRADE_VERSION}`, - `stdout: ${stdout}\nstderr: ${stderr}`, - ); - } + // Check the version of the "upgraded" `deployctl` + { + const versionCmd = await new Deno.Command(`${tempDir}/bin/deployctl`, { + args: ["--version"], + }).output(); + const stdout = decoder.decode(versionCmd.stdout).trim(); + const stderr = decoder.decode(versionCmd.stderr).trim(); + assert(versionCmd.success); + assertEquals( + stdout, + `deployctl ${UPGRADE_VERSION}`, + `stdout: ${stdout}\nstderr: ${stderr}`, + ); + } }); From b115bd2c8fd320bacf5d311b00d4e5b02f066829 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Fri, 25 Oct 2024 19:01:19 +0900 Subject: [PATCH 4/4] fix for windows --- tests/upgrade_test.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/upgrade_test.ts b/tests/upgrade_test.ts index 577cbc2..7b688c4 100644 --- a/tests/upgrade_test.ts +++ b/tests/upgrade_test.ts @@ -11,6 +11,8 @@ Deno.test("upgrade", async () => { const tempDir = await Deno.makeTempDir(); console.log(tempDir); + const exe = Deno.build.os === "windows" ? "deployctl.cmd" : "deployctl"; + // Install the current `deployctl.ts` { const installCmd = await new Deno.Command(Deno.execPath(), { @@ -34,7 +36,7 @@ Deno.test("upgrade", async () => { // Check the version of the installed `deployctl` { - const versionCmd = await new Deno.Command(`${tempDir}/bin/deployctl`, { + const versionCmd = await new Deno.Command(`${tempDir}/bin/${exe}`, { args: ["--version"], }).output(); const stdout = decoder.decode(versionCmd.stdout).trim(); @@ -51,7 +53,7 @@ Deno.test("upgrade", async () => { // "Upgrade" the installed `deployctl` to 1.12.0 { - const upgradeCmd = await new Deno.Command(`${tempDir}/bin/deployctl`, { + const upgradeCmd = await new Deno.Command(`${tempDir}/bin/${exe}`, { args: [ "upgrade", "--root", @@ -66,7 +68,7 @@ Deno.test("upgrade", async () => { // Check the version of the "upgraded" `deployctl` { - const versionCmd = await new Deno.Command(`${tempDir}/bin/deployctl`, { + const versionCmd = await new Deno.Command(`${tempDir}/bin/${exe}`, { args: ["--version"], }).output(); const stdout = decoder.decode(versionCmd.stdout).trim();