diff --git a/README.md b/README.md index d3c3d7f..473435e 100644 --- a/README.md +++ b/README.md @@ -28,19 +28,20 @@ Calling `drenv` without any arguments will also display this message. ``` Usage: drenv [options] [command] -CLI to manage DragonRuby environments. +CLI to manage DragonRuby environments Options: -V, --version output the version number -h, --help display help for command Commands: - setup Setup your shell profile to use drenv. - new Create a new DragonRuby project. - register Register a DragonRuby installation. This moves the installation to the $HOME/.drenv directory. - global [version] Get or set the global version of DragonRuby. - local [version] Get or set the local version of DragonRuby. - versions List out all locally installed versions of DragonRuby. + setup Setup your shell profile to use drenv + new Create a new DragonRuby project + register Register a DragonRuby installation + global [version] Get or set the global version of DragonRuby + local [version] Get or set the local version of DragonRuby + versions List out all locally installed versions of DragonRuby + upgrade Upgrade the version of drenv help [command] display help for command ``` @@ -60,11 +61,14 @@ into **drenv**'s home directory. > You will need to register at least one DragonRuby installation before you can > use **drenv**. -### `drenv global ` +### `drenv global [version]` This command sets the version of DragonRuby that **drenv** will use when creating new projects. +If you call `drenv global` without any arguments, it will display the current +global version. + ### `drenv new ` This command will create a new DragonRuby project with the specified name. @@ -81,13 +85,19 @@ Under the hood, all **drenv** does is copy the contents of the global DragonRuby installation into the current project directory, excluding the `mygame` directory. +### `drenv upgrade` + +This command will download and upgrade your **drenv** installation to the latest +version. + ### `drenv versions` This command will list out all registered versions of DragonRuby. ``` 5.32 + 6.4 * 6.3 ``` -Tested on MacOS Macbook Pro M1 with DragonRuby 5.32 and 6.3. +Tested on MacOS Macbook Pro M1 with DragonRuby 5.32, 6.3, and 6.4. diff --git a/commands/upgrade.ts b/commands/upgrade.ts new file mode 100644 index 0000000..9a8e602 --- /dev/null +++ b/commands/upgrade.ts @@ -0,0 +1,62 @@ +import { greaterThan, parse } from "jsr:@std/semver"; + +import { program } from "../main.ts"; +import { drenvBinPath, version } from "../constants.ts"; + +type Asset = { + url: string; + id: number; + node_id: string; + name: string; + label: string | null; + uploader: any; + content_type: string; + state: string; + size: number; + download_count: number; + created_at: string; + updated_at: string; + browser_download_url: string; +}; + +export default async function upgrade() { + console.log(`Current version is v${program.version()}`); + console.log("Checking for updates..."); + + const dataResponse = await fetch( + "https://api.github.com/repos/nitemaeric/drenv/releases/latest", + ); + const data = await dataResponse.json(); + + const localVersion = parse(version); + const remoteVersion = parse(data.tag_name.slice(1)); + + if (greaterThan(remoteVersion, localVersion)) { + console.log(`New version found: ${data.tag_name}`); + + const file = await Deno.open(drenvBinPath, { write: true, create: true }); + + const targetAsset = data.assets.find((asset: Asset) => + asset.name.includes(Deno.build.target) + ); + + if (targetAsset) { + console.log(`Downloading new version...`); + + const downloadResponse = await fetch(targetAsset.browser_download_url); + + if (!downloadResponse.body) { + throw new Error("Could not download the new version"); + } + + await downloadResponse.body.pipeTo(file.writable); + await Deno.chmod(drenvBinPath, 0o755); + + console.log(`Upgraded to ${data.tag_name}`); + } else { + console.log("No asset found for your platform"); + } + } else { + console.log("Already up-to-date"); + } +} diff --git a/constants.ts b/constants.ts index e80e43c..aa3f020 100644 --- a/constants.ts +++ b/constants.ts @@ -1,4 +1,6 @@ +export const version = "0.3.0"; export const homePath = `${Deno.env.get("HOME")}/.drenv`; export const versionsPath = `${homePath}/versions`; export const binPath = `${homePath}/bin`; +export const drenvBinPath = `${binPath}/drenv`; export const shell = Deno.env.get("SHELL"); diff --git a/deno.lock b/deno.lock index 8393e4d..7692c2a 100644 --- a/deno.lock +++ b/deno.lock @@ -6,6 +6,7 @@ "jsr:@std/fs@^1.0.4": "1.0.4", "jsr:@std/internal@^1.0.4": "1.0.4", "jsr:@std/path@^1.0.6": "1.0.6", + "jsr:@std/semver@*": "1.0.3", "npm:commander@*": "12.1.0", "npm:commander@^12.1.0": "12.1.0" }, @@ -27,6 +28,9 @@ }, "@std/path@1.0.6": { "integrity": "ab2c55f902b380cf28e0eec501b4906e4c1960d13f00e11cfbcd21de15f18fed" + }, + "@std/semver@1.0.3": { + "integrity": "7c139c6076a080eeaa4252c78b95ca5302818d7eafab0470d34cafd9930c13c8" } }, "npm": { diff --git a/main.ts b/main.ts index f55659c..0ca4998 100644 --- a/main.ts +++ b/main.ts @@ -5,9 +5,12 @@ import local from "./commands/local.ts"; import newCommand from "./commands/new.ts"; import register from "./commands/register.ts"; import setup from "./commands/setup.ts"; +import upgrade from "./commands/upgrade.ts"; import versions from "./commands/versions.ts"; -const program = new Command(); +import { version } from "./constants.ts"; + +export const program = new Command(); const actionRunner = (fn: (...args: any[]) => Promise) => { return (...args: any[]): any => @@ -24,20 +27,21 @@ const actionRunner = (fn: (...args: any[]) => Promise) => { program .name("drenv") - .description("CLI to manage DragonRuby environments.") - .version("0.2.3"); + .description("CLI to manage DragonRuby environments") + .version(version); program.command("setup") - .description("Setup your shell profile to use drenv.") + .description("Setup your shell profile to use drenv") .action(actionRunner(setup)); program.command("new") .argument("", "Name of the new project") - .description("Create a new DragonRuby project.") + .description("Create a new DragonRuby project") .action(actionRunner(newCommand)); program.command("register") .argument("", "Path to a fresh DragonRuby directory") + .summary("Register a DragonRuby installation") .description( "Register a DragonRuby installation. This moves the installation to the $HOME/.drenv directory.", ) @@ -45,16 +49,20 @@ program.command("register") program.command("global") .argument("[version]", "Version of DragonRuby to use") - .description("Get or set the global version of DragonRuby.") + .description("Get or set the global version of DragonRuby") .action(actionRunner(global)); program.command("local") .argument("[version]", "Version of DragonRuby to use") - .description("Get or set the local version of DragonRuby.") + .description("Get or set the local version of DragonRuby") .action(actionRunner(local)); program.command("versions") - .description("List out all locally installed versions of DragonRuby.") + .description("List out all locally installed versions of DragonRuby") .action(actionRunner(versions)); +program.command("upgrade") + .description("Upgrade the version of drenv") + .action(actionRunner(upgrade)); + program.parse();