From b0a1e3c7e2932f4f61f64bd9b55daa6ef7fcba1d Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Wed, 8 Nov 2023 18:59:44 +0200 Subject: [PATCH 01/16] Add ability to chose what version of swanky node. Add node version command. Fix node start command. Add node version to check command. --- src/commands/check/index.ts | 7 ++ src/commands/init/index.ts | 22 ++++-- src/commands/node/install.ts | 33 +++++++-- src/commands/node/start.ts | 6 +- src/commands/node/version.ts | 12 ++++ src/lib/consts.ts | 16 +++++ src/lib/nodeInfo.ts | 132 +++++++++++++++++++++++++++++++---- src/lib/prompts.ts | 10 +++ src/types/index.ts | 3 +- 9 files changed, 217 insertions(+), 24 deletions(-) create mode 100644 src/commands/node/version.ts diff --git a/src/commands/check/index.ts b/src/commands/check/index.ts index 9d1d27fa..8af906ae 100644 --- a/src/commands/check/index.ts +++ b/src/commands/check/index.ts @@ -18,6 +18,7 @@ interface Ctx { cargoContract?: string | null; }; contracts: Record>; + node?: string | null; }; swankyConfig?: SwankyConfig; mismatchedVersions?: Record; @@ -59,6 +60,12 @@ export default class Check extends SwankyCommand { ctx.versions.tools.cargoContract = await commandStdoutOrNull("cargo contract -V"); }, }, + { + title: "Check swanky node", + task: async (ctx) => { + ctx.versions.node = this.swankyConfig.node.version !== "" ? this.swankyConfig.node.version : null; + }, + }, { title: "Read ink dependencies", task: async (ctx) => { diff --git a/src/commands/init/index.ts b/src/commands/init/index.ts index 45177372..dcadba43 100644 --- a/src/commands/init/index.ts +++ b/src/commands/init/index.ts @@ -6,7 +6,7 @@ import { execaCommand, execaCommandSync } from "execa"; import { paramCase, pascalCase, snakeCase } from "change-case"; import inquirer from "inquirer"; import TOML from "@iarna/toml"; -import { choice, email, name, pickTemplate } from "../../lib/prompts.js"; +import { choice, email, name, pickNodeVersion, pickTemplate } from "../../lib/prompts.js"; import { checkCliDependencies, copyCommonTemplateFiles, @@ -20,7 +20,7 @@ import { } from "../../lib/index.js"; import { DEFAULT_ASTAR_NETWORK_URL, - DEFAULT_NETWORK_URL, + DEFAULT_NETWORK_URL, DEFAULT_NODE_INFO, DEFAULT_SHIBUYA_NETWORK_URL, DEFAULT_SHIDEN_NETWORK_URL, } from "../../lib/consts.js"; @@ -93,11 +93,13 @@ export class Init extends SwankyCommand { } projectPath = ""; + configBuilder: Partial = { node: { localPath: "", - polkadotPalletVersions: swankyNode.polkadotPalletVersions, - supportedInk: swankyNode.supportedInk, + polkadotPalletVersions: "", + supportedInk: "", + version: "", }, accounts: [], networks: { @@ -161,9 +163,19 @@ export class Init extends SwankyCommand { choice("useSwankyNode", "Do you want to download Swanky node?"), ]); if (useSwankyNode) { + const versions = Array.from(swankyNode.keys()); + let nodeVersion = DEFAULT_NODE_INFO.version; + await inquirer.prompt([ + pickNodeVersion(versions), + ]).then((answers) => { + nodeVersion = answers.version; + }); + + const nodeInfo = swankyNode.get(nodeVersion)!; + this.taskQueue.push({ task: downloadNode, - args: [this.projectPath, swankyNode, this.spinner], + args: [this.projectPath, nodeInfo, this.spinner], runningMessage: "Downloading Swanky node", callback: (result) => this.configBuilder.node ? (this.configBuilder.node.localPath = result) : null, diff --git a/src/commands/node/install.ts b/src/commands/node/install.ts index 8d9beb5e..58c50cdf 100644 --- a/src/commands/node/install.ts +++ b/src/commands/node/install.ts @@ -1,17 +1,38 @@ import { SwankyCommand } from "../../lib/swankyCommand.js"; -import { ux } from "@oclif/core"; +import { ux, Flags } from "@oclif/core"; import { downloadNode, swankyNode } from "../../lib/index.js"; import path from "node:path"; import { writeJSON } from "fs-extra/esm"; +import inquirer from "inquirer"; +import { DEFAULT_NODE_INFO } from "../../lib/consts.js"; +import { pickNodeVersion } from "../../lib/prompts.js"; export class InstallNode extends SwankyCommand { static description = "Install swanky node binary"; + static flags = { + "set-version": Flags.string({ + description: "Specify version of swanky node to install", + required: false, + }), + } async run(): Promise { const { flags } = await this.parse(InstallNode); if (flags.verbose) { this.spinner.verbose = true; } + let nodeVersion= DEFAULT_NODE_INFO.version; + + if (flags.specifyVersion) { + nodeVersion = flags.specifyVersion; + } else { + const versions = Array.from(swankyNode.keys()); + await inquirer.prompt([ + pickNodeVersion(versions), + ]).then((answers) => { + nodeVersion = answers.version; + }); + } const projectPath = path.resolve(); @@ -24,16 +45,20 @@ export class InstallNode extends SwankyCommand { } } + const nodeInfo = swankyNode.get(nodeVersion)!; + const taskResult = (await this.spinner.runCommand( - () => downloadNode(projectPath, swankyNode, this.spinner), + () => downloadNode(projectPath, nodeInfo, this.spinner), "Downloading Swanky node" )) as string; const nodePath = path.relative(projectPath, taskResult); + this.swankyConfig.node = { localPath: nodePath, - polkadotPalletVersions: swankyNode.polkadotPalletVersions, - supportedInk: swankyNode.supportedInk, + polkadotPalletVersions: nodeInfo.polkadotPalletVersions, + supportedInk: nodeInfo.supportedInk, + version: nodeInfo.version, }; await this.spinner.runCommand( diff --git a/src/commands/node/start.ts b/src/commands/node/start.ts index cb976870..097becc7 100644 --- a/src/commands/node/start.ts +++ b/src/commands/node/start.ts @@ -28,11 +28,15 @@ export class StartNode extends SwankyCommand { async run(): Promise { const { flags } = await this.parse(StartNode); + if (this.swankyConfig.node.version === "") { + this.log("Node is not installed"); + return; + } // Run persistent mode by default. non-persistent mode in case flag is provided. // Non-Persistent mode (`--dev`) allows all CORS origin, without `--dev`, users need to specify origins by `--rpc-cors`. await execaCommand( `${this.swankyConfig.node.localPath} \ - --finalize-delay-sec ${flags.finalizeDelaySec} \ + ${this.swankyConfig.node.version === "1.6.0" ? `--finalize-delay-sec ${flags.finalizeDelaySec}` : ""} \ ${flags.tmp ? "--dev" : `--rpc-cors ${flags.rpcCors}`}`, { stdio: "inherit", diff --git a/src/commands/node/version.ts b/src/commands/node/version.ts new file mode 100644 index 00000000..b34a0305 --- /dev/null +++ b/src/commands/node/version.ts @@ -0,0 +1,12 @@ +import { SwankyCommand } from "../../lib/swankyCommand.js"; +export class NodeVersion extends SwankyCommand { + static description = "Show swanky node version"; + async run(): Promise { + if(this.swankyConfig.node.version === ""){ + this.log("Node is not installed"); + } + else { + this.log(`Node version: ${this.swankyConfig.node.version}`); + } + } +} diff --git a/src/lib/consts.ts b/src/lib/consts.ts index d48b2b67..b4d996d4 100644 --- a/src/lib/consts.ts +++ b/src/lib/consts.ts @@ -5,3 +5,19 @@ export const DEFAULT_SHIBUYA_NETWORK_URL = "wss://shibuya.public.blastapi.io"; export const ARTIFACTS_PATH = "artifacts"; export const TYPED_CONTRACTS_PATH = "typedContracts"; + +export const DEFAULT_NODE_INFO = { + version: "1.6.0", + polkadotPalletVersions: "polkadot-v0.9.39", + supportedInk: "v4.2.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-macOS-universal.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-macOS-universal.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-ubuntu-aarch64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-ubuntu-x86_64.tar.gz", + } + } +} diff --git a/src/lib/nodeInfo.ts b/src/lib/nodeInfo.ts index 3064488a..696feeb1 100644 --- a/src/lib/nodeInfo.ts +++ b/src/lib/nodeInfo.ts @@ -1,17 +1,123 @@ -export type nodeInfo = typeof swankyNode; - -export const swankyNode = { - version: "1.6.0", - polkadotPalletVersions: "polkadot-v0.9.39", - supportedInk: "v4.2.0", +export interface nodeInfo { + version: string; + polkadotPalletVersions: string; + supportedInk: string; downloadUrl: { darwin: { - "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-macOS-universal.tar.gz", - "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-macOS-universal.tar.gz" - }, + "arm64"?: string; + "x64"?: string; + }; linux: { - "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-ubuntu-aarch64.tar.gz", - "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-ubuntu-x86_64.tar.gz", + "arm64"?: string; + "x64"?: string; + }; + }; +} + +export const swankyNode = new Map([ + ["1.6.0", { + version: "1.6.0", + polkadotPalletVersions: "polkadot-v0.9.39", + supportedInk: "v4.2.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-macOS-universal.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-macOS-universal.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-ubuntu-aarch64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-ubuntu-x86_64.tar.gz", + } + } + }], + ["1.5.0", { + version: "1.5.0", + polkadotPalletVersions: "polkadot-v0.9.39", + supportedInk: "v4.0.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.5.0/swanky-node-v1.5.0-macOS-universal.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.5.0/swanky-node-v1.5.0-macOS-universal.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.5.0/swanky-node-v1.5.0-ubuntu-aarch64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.5.0/swanky-node-v1.5.0-ubuntu-x86_64.tar.gz", + } + } + }], + ["1.4.0", { + version: "1.4.0", + polkadotPalletVersions: "polkadot-v0.9.37", + supportedInk: "v4.0.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.4.0/swanky-node-v1.4.0-macOS-universal.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.4.0/swanky-node-v1.4.0-macOS-universal.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.4.0/swanky-node-v1.4.0-ubuntu-aarch64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.4.0/swanky-node-v1.4.0-ubuntu-x86_64.tar.gz", + } + } + }], + ["1.3.0", { + version: "1.3.0", + polkadotPalletVersions: "polkadot-v0.9.37", + supportedInk: "v4.0.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.3.0/swanky-node-v1.3.0-macOS-universal.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.3.0/swanky-node-v1.3.0-macOS-universal.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.3.0/swanky-node-v1.3.0-ubuntu-aarch64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.3.0/swanky-node-v1.3.0-ubuntu-x86_64.tar.gz", + } + } + }], + ["1.2.0", { + version: "1.2.0", + polkadotPalletVersions: "polkadot-v0.9.37", + supportedInk: "v4.0.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.2.0/swanky-node-v1.2.0-macOS-universal.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.2.0/swanky-node-v1.2.0-macOS-universal.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.2.0/swanky-node-v1.2.0-ubuntu-aarch64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.2.0/swanky-node-v1.2.0-ubuntu-x86_64.tar.gz", + } + } + }], + ["1.1.0", { + version: "1.1.0", + polkadotPalletVersions: "polkadot-v0.9.37", + supportedInk: "v4.0.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.1.0/swanky-node-v1.1.0-macOS-x86_64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.1.0/swanky-node-v1.1.0-macOS-x86_64.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.1.0/swanky-node-v1.1.0-ubuntu-x86_64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.1.0/swanky-node-v1.1.0-ubuntu-x86_64.tar.gz", + } + } + }], + ["1.0.0", { + version: "1.0.0", + polkadotPalletVersions: "polkadot-v0.9.30", + supportedInk: "v3.4.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.0.0/swanky-node-v1.0.0-macOS-x86_64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.0.0/swanky-node-v1.0.0-macOS-x86_64.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.0.0/swanky-node-v1.0.0-ubuntu-x86_64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.0.0/swanky-node-v1.0.0-ubuntu-x86_64.tar.gz", + } } - }, -}; + }] +]); diff --git a/src/lib/prompts.ts b/src/lib/prompts.ts index 259c45a9..3ee17625 100644 --- a/src/lib/prompts.ts +++ b/src/lib/prompts.ts @@ -11,6 +11,16 @@ export function pickTemplate(templateList: string[]): ListQuestion { }; } +export function pickNodeVersion(nodeVersions: string[]): ListQuestion { + if (!nodeVersions?.length) throw new ConfigError("Node version list is empty!"); + return { + name: "version", + type: "list", + choices: nodeVersions, + message: "Which node version should we use?", + }; +} + export function name( subject: string, initial?: (answers: Answers) => string, diff --git a/src/types/index.ts b/src/types/index.ts index aa13a0df..7ff5b9f6 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -11,7 +11,7 @@ export interface ChainProperty { export type ExtrinsicPayload = SubmittableExtrinsic<"promise">; -export interface Encrypted { iv: string; data: string }; +export interface Encrypted { iv: string; data: string } export interface AccountData { isDev: boolean; @@ -43,6 +43,7 @@ export interface SwankyConfig { polkadotPalletVersions: string; localPath: string; supportedInk: string; + version: string; }; accounts: AccountData[]; contracts: Record | Record; From 40e2c396df8f4ddd2df5a060da5953ced7342624 Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Thu, 9 Nov 2023 11:12:43 +0200 Subject: [PATCH 02/16] Fix SwankyConfig update while downloading node --- src/commands/init/index.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/commands/init/index.ts b/src/commands/init/index.ts index dcadba43..6c8d758d 100644 --- a/src/commands/init/index.ts +++ b/src/commands/init/index.ts @@ -177,8 +177,14 @@ export class Init extends SwankyCommand { task: downloadNode, args: [this.projectPath, nodeInfo, this.spinner], runningMessage: "Downloading Swanky node", - callback: (result) => - this.configBuilder.node ? (this.configBuilder.node.localPath = result) : null, + callback: (result) => { + this.configBuilder.node = { + supportedInk: nodeInfo.supportedInk, + polkadotPalletVersions: nodeInfo.polkadotPalletVersions, + version: nodeInfo.version, + localPath: result, + }; + } }); } } From 8215a19ae760da97b0c8fb378af8472dcb1e2851 Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Mon, 27 Nov 2023 10:30:40 +0200 Subject: [PATCH 03/16] Add platform and arch to check --- src/commands/check/index.ts | 64 ++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/src/commands/check/index.ts b/src/commands/check/index.ts index 8af906ae..6d3a616f 100644 --- a/src/commands/check/index.ts +++ b/src/commands/check/index.ts @@ -1,14 +1,20 @@ import { Listr } from "listr2"; import { commandStdoutOrNull } from "../../lib/index.js"; import { SwankyConfig } from "../../types/index.js"; -import { pathExistsSync, readJSON } from "fs-extra/esm"; +import { pathExistsSync, readJSON, writeJson } from "fs-extra/esm"; import { readFileSync } from "fs"; import path from "node:path"; import TOML from "@iarna/toml"; import semver from "semver"; import { SwankyCommand } from "../../lib/swankyCommand.js"; +import { Flags } from "@oclif/core"; +import chalk from "chalk"; interface Ctx { + os: { + platform: string; + architecture: string; + }, versions: { tools: { rust?: string | null; @@ -17,6 +23,7 @@ interface Ctx { cargoDylint?: string | null; cargoContract?: string | null; }; + missingTools: string[]; contracts: Record>; node?: string | null; }; @@ -28,8 +35,23 @@ interface Ctx { export default class Check extends SwankyCommand { static description = "Check installed package versions and compatibility"; + static flags = { + file: Flags.string({ + char: "f", + description: "File to write output to", + }) + }; + public async run(): Promise { + const { flags } = await this.parse(Check); const tasks = new Listr([ + { + title: "Check OS", + task: async (ctx) => { + ctx.os.platform = process.platform; + ctx.os.architecture = process.arch; + }, + }, { title: "Check Rust", task: async (ctx) => { @@ -86,7 +108,7 @@ export default class Check extends SwankyCommand { const cargoToml = TOML.parse(cargoTomlString); const inkDependencies = Object.entries(cargoToml.dependencies) - .filter((dependency) => dependency[0].includes("ink_")) + .filter((dependency) => dependency[0].includes("ink")) .map(([depName, depInfo]) => { const dependency = depInfo as Dependency; return [depName, dependency.version ?? dependency.tag]; @@ -118,12 +140,27 @@ export default class Check extends SwankyCommand { ctx.mismatchedVersions = mismatched; }, }, + { + title: "Check for missing tools", + task: async (ctx) => { + const missingTools: string[] = []; + for (const [toolName, toolVersion] of Object.entries(ctx.versions.tools)) { + if (!toolVersion) { + missingTools.push(toolName); + } + } + ctx.versions.missingTools = missingTools; + }, + } ]); + process.platform + process.arch const context = await tasks.run({ - versions: { tools: {}, contracts: {} }, + os: { platform: "", architecture: "" }, + versions: {tools: {}, missingTools: [], contracts: {} }, looseDefinitionDetected: false, }); - console.log(context.versions); + Object.values(context.mismatchedVersions as any).forEach((mismatch) => console.error(`[ERROR] ${mismatch as string}`) ); @@ -133,9 +170,26 @@ export default class Check extends SwankyCommand { Please use "=" to install a fixed version (Example: "=3.0.1") `); } + const supportedPlatforms = ["darwin", "linux"]; + const supportedArch = ["arm64", "x64"]; + + if (!supportedPlatforms.includes(context.os.platform)) { + console.error(`[ERROR] Platform ${context.os.platform} is not supported`); + } + if (!supportedArch.includes(context.os.architecture)) { + console.error(`[ERROR] Architecture ${context.os.architecture} is not supported`); + } + + console.log(context.os, context.versions); + + const filePath = flags.file ?? null; + if(filePath) { + await this.spinner.runCommand(async () => { + writeJson(filePath, [context.os, context.versions], { spaces: 2 }) + }, `Writing output to file ${chalk.yellowBright(filePath)}`) + } } } - interface Dependency { version?: string; tag?: string; From c15b488e9a24644fab53c6e048b85fd68a5fd9e6 Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Fri, 1 Dec 2023 23:55:25 +0200 Subject: [PATCH 04/16] Add cargo-contract -> ink! dependency table --- src/commands/check/index.ts | 15 ++++++++++++++- src/lib/cargoContractInfo.ts | 12 ++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/lib/cargoContractInfo.ts diff --git a/src/commands/check/index.ts b/src/commands/check/index.ts index 6d3a616f..60949db2 100644 --- a/src/commands/check/index.ts +++ b/src/commands/check/index.ts @@ -9,6 +9,7 @@ import semver from "semver"; import { SwankyCommand } from "../../lib/swankyCommand.js"; import { Flags } from "@oclif/core"; import chalk from "chalk"; +import { cargoContractDeps } from "../../lib/cargoContractInfo.js"; interface Ctx { os: { @@ -120,7 +121,19 @@ export default class Check extends SwankyCommand { { title: "Verify ink version", task: async (ctx) => { - const supportedInk = ctx.swankyConfig?.node.supportedInk; + let supportedInk = ctx.swankyConfig?.node.supportedInk; + const regex = /cargo-contract-contract (.*)-unknown-x86_64-unknown-linux-gnu/; + const cargoContract = ctx.versions.tools.cargoContract; + if (cargoContract) { + const match = cargoContract.match(regex); + if (match) { + const cargoVersion = match[1]; + const version = cargoContractDeps.get(cargoVersion); + if (version && semver.gt(supportedInk!, version[0])) { + supportedInk = version[0]; + } + } + } const mismatched: Record = {}; Object.entries(ctx.versions.contracts).forEach(([contract, inkPackages]) => { diff --git a/src/lib/cargoContractInfo.ts b/src/lib/cargoContractInfo.ts new file mode 100644 index 00000000..8db616d3 --- /dev/null +++ b/src/lib/cargoContractInfo.ts @@ -0,0 +1,12 @@ +export type cargoContractInfo = typeof cargoContractDeps; + +export const cargoContractDeps = new Map([ + ["3.2.0", + ["4.0.0-alpha.3", "4.0.0"]], + ["4.0.0-alpha", + ["5.0.0-alpha", "5.0.0"]], + ["4.0.0-rc", + ["5.0.0-alpha", "5.0.0"]], + ["4.0.0-rc.1", + ["5.0.0-alpha", "5.0.0"]] +]); From c0602b64fbf776893e5c6a8630acad6b663e567e Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Thu, 18 Jan 2024 22:56:46 +0200 Subject: [PATCH 05/16] Fixes --- src/commands/init/index.ts | 7 +++---- src/commands/node/install.ts | 16 ++++++++++------ src/commands/node/start.ts | 3 ++- src/commands/node/version.ts | 4 ++-- src/lib/consts.ts | 18 +++--------------- src/lib/nodeInfo.ts | 2 +- 6 files changed, 21 insertions(+), 29 deletions(-) diff --git a/src/commands/init/index.ts b/src/commands/init/index.ts index 6c8d758d..e7141b40 100644 --- a/src/commands/init/index.ts +++ b/src/commands/init/index.ts @@ -15,8 +15,7 @@ import { installDeps, ChainAccount, processTemplates, - swankyNode, - getTemplates, + getTemplates, swankyNodeVersions, } from "../../lib/index.js"; import { DEFAULT_ASTAR_NETWORK_URL, @@ -163,7 +162,7 @@ export class Init extends SwankyCommand { choice("useSwankyNode", "Do you want to download Swanky node?"), ]); if (useSwankyNode) { - const versions = Array.from(swankyNode.keys()); + const versions = Array.from(swankyNodeVersions.keys()); let nodeVersion = DEFAULT_NODE_INFO.version; await inquirer.prompt([ pickNodeVersion(versions), @@ -171,7 +170,7 @@ export class Init extends SwankyCommand { nodeVersion = answers.version; }); - const nodeInfo = swankyNode.get(nodeVersion)!; + const nodeInfo = swankyNodeVersions.get(nodeVersion)!; this.taskQueue.push({ task: downloadNode, diff --git a/src/commands/node/install.ts b/src/commands/node/install.ts index 58c50cdf..af90048c 100644 --- a/src/commands/node/install.ts +++ b/src/commands/node/install.ts @@ -1,18 +1,19 @@ import { SwankyCommand } from "../../lib/swankyCommand.js"; import { ux, Flags } from "@oclif/core"; -import { downloadNode, swankyNode } from "../../lib/index.js"; +import { downloadNode, swankyNodeVersions } from "../../lib/index.js"; import path from "node:path"; import { writeJSON } from "fs-extra/esm"; import inquirer from "inquirer"; import { DEFAULT_NODE_INFO } from "../../lib/consts.js"; import { pickNodeVersion } from "../../lib/prompts.js"; +import { InputError } from "../../lib/errors.js"; export class InstallNode extends SwankyCommand { static description = "Install swanky node binary"; static flags = { "set-version": Flags.string({ - description: "Specify version of swanky node to install", + description: "Specify version of swanky node to install. \n List of supported versions: " + Array.from(swankyNodeVersions.keys()).join(", "), required: false, }), } @@ -23,10 +24,13 @@ export class InstallNode extends SwankyCommand { } let nodeVersion= DEFAULT_NODE_INFO.version; - if (flags.specifyVersion) { - nodeVersion = flags.specifyVersion; + if (flags["set-version"]) { + nodeVersion = flags["set-version"]; + if(!swankyNodeVersions.has(nodeVersion)) { + throw new InputError(`Version ${nodeVersion} is not supported.\n List of supported versions: ${Array.from(swankyNodeVersions.keys()).join(", ")}`); + } } else { - const versions = Array.from(swankyNode.keys()); + const versions = Array.from(swankyNodeVersions.keys()); await inquirer.prompt([ pickNodeVersion(versions), ]).then((answers) => { @@ -45,7 +49,7 @@ export class InstallNode extends SwankyCommand { } } - const nodeInfo = swankyNode.get(nodeVersion)!; + const nodeInfo = swankyNodeVersions.get(nodeVersion)!; const taskResult = (await this.spinner.runCommand( () => downloadNode(projectPath, nodeInfo, this.spinner), diff --git a/src/commands/node/start.ts b/src/commands/node/start.ts index 097becc7..a0984998 100644 --- a/src/commands/node/start.ts +++ b/src/commands/node/start.ts @@ -1,6 +1,7 @@ import { Flags } from "@oclif/core"; import { execaCommand } from "execa"; import { SwankyCommand } from "../../lib/swankyCommand.js"; +import semver from "semver"; export class StartNode extends SwankyCommand { static description = "Start a local node"; @@ -36,7 +37,7 @@ export class StartNode extends SwankyCommand { // Non-Persistent mode (`--dev`) allows all CORS origin, without `--dev`, users need to specify origins by `--rpc-cors`. await execaCommand( `${this.swankyConfig.node.localPath} \ - ${this.swankyConfig.node.version === "1.6.0" ? `--finalize-delay-sec ${flags.finalizeDelaySec}` : ""} \ + ${ semver.gt(this.swankyConfig.node.version, "1.6.0") ? `--finalize-delay-sec ${flags.finalizeDelaySec}` : ""} \ ${flags.tmp ? "--dev" : `--rpc-cors ${flags.rpcCors}`}`, { stdio: "inherit", diff --git a/src/commands/node/version.ts b/src/commands/node/version.ts index b34a0305..a6937d09 100644 --- a/src/commands/node/version.ts +++ b/src/commands/node/version.ts @@ -3,10 +3,10 @@ export class NodeVersion extends SwankyCommand { static description = "Show swanky node version"; async run(): Promise { if(this.swankyConfig.node.version === ""){ - this.log("Node is not installed"); + this.log("Swanky node is not installed"); } else { - this.log(`Node version: ${this.swankyConfig.node.version}`); + this.log(`Swanky node version: ${this.swankyConfig.node.version}`); } } } diff --git a/src/lib/consts.ts b/src/lib/consts.ts index b4d996d4..ed9e063b 100644 --- a/src/lib/consts.ts +++ b/src/lib/consts.ts @@ -1,3 +1,5 @@ +import { swankyNodeVersions } from "./nodeInfo.js"; + export const DEFAULT_NETWORK_URL = "ws://127.0.0.1:9944"; export const DEFAULT_ASTAR_NETWORK_URL = "wss://rpc.astar.network"; export const DEFAULT_SHIDEN_NETWORK_URL = "wss://rpc.shiden.astar.network"; @@ -6,18 +8,4 @@ export const DEFAULT_SHIBUYA_NETWORK_URL = "wss://shibuya.public.blastapi.io"; export const ARTIFACTS_PATH = "artifacts"; export const TYPED_CONTRACTS_PATH = "typedContracts"; -export const DEFAULT_NODE_INFO = { - version: "1.6.0", - polkadotPalletVersions: "polkadot-v0.9.39", - supportedInk: "v4.2.0", - downloadUrl: { - darwin: { - "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-macOS-universal.tar.gz", - "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-macOS-universal.tar.gz" - }, - linux: { - "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-ubuntu-aarch64.tar.gz", - "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-ubuntu-x86_64.tar.gz", - } - } -} +export const DEFAULT_NODE_INFO = swankyNodeVersions.get("1.6.0")!; diff --git a/src/lib/nodeInfo.ts b/src/lib/nodeInfo.ts index 696feeb1..60a6d1f0 100644 --- a/src/lib/nodeInfo.ts +++ b/src/lib/nodeInfo.ts @@ -14,7 +14,7 @@ export interface nodeInfo { }; } -export const swankyNode = new Map([ +export const swankyNodeVersions = new Map([ ["1.6.0", { version: "1.6.0", polkadotPalletVersions: "polkadot-v0.9.39", From 28e374fff7d35b16f374ec24ee15b2f081cdc5ea Mon Sep 17 00:00:00 2001 From: Igor Papandinas Date: Tue, 23 Jan 2024 18:33:30 +0100 Subject: [PATCH 06/16] fix: Greater or equal to 1.6.0 versions are supported --- src/commands/node/start.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/node/start.ts b/src/commands/node/start.ts index a0984998..e92e65e6 100644 --- a/src/commands/node/start.ts +++ b/src/commands/node/start.ts @@ -37,7 +37,7 @@ export class StartNode extends SwankyCommand { // Non-Persistent mode (`--dev`) allows all CORS origin, without `--dev`, users need to specify origins by `--rpc-cors`. await execaCommand( `${this.swankyConfig.node.localPath} \ - ${ semver.gt(this.swankyConfig.node.version, "1.6.0") ? `--finalize-delay-sec ${flags.finalizeDelaySec}` : ""} \ + ${ semver.gte(this.swankyConfig.node.version, "1.6.0") ? `--finalize-delay-sec ${flags.finalizeDelaySec}` : ""} \ ${flags.tmp ? "--dev" : `--rpc-cors ${flags.rpcCors}`}`, { stdio: "inherit", From 704864b65c6d587c1cb602b3653df387d99136a9 Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Sat, 27 Jan 2024 00:23:49 +0200 Subject: [PATCH 07/16] Fixes --- src/commands/check/index.ts | 112 +++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 32 deletions(-) diff --git a/src/commands/check/index.ts b/src/commands/check/index.ts index 60949db2..ace7f2e8 100644 --- a/src/commands/check/index.ts +++ b/src/commands/check/index.ts @@ -24,6 +24,7 @@ interface Ctx { cargoDylint?: string | null; cargoContract?: string | null; }; + supportedInk?: string; missingTools: string[]; contracts: Record>; node?: string | null; @@ -40,7 +41,7 @@ export default class Check extends SwankyCommand { file: Flags.string({ char: "f", description: "File to write output to", - }) + }), }; public async run(): Promise { @@ -51,43 +52,84 @@ export default class Check extends SwankyCommand { task: async (ctx) => { ctx.os.platform = process.platform; ctx.os.architecture = process.arch; + const supportedPlatforms = ["darwin", "linux"]; + const supportedArch = ["arm64", "x64"]; + + if (!supportedPlatforms.includes(ctx.os.platform)) { + throw new Error(`Platform ${ctx.os.platform} is not supported!`); + } + if (!supportedArch.includes(ctx.os.architecture)) { + throw new Error(`Architecture ${ctx.os.architecture} is not supported!`); + } }, + exitOnError: false, }, { title: "Check Rust", task: async (ctx) => { ctx.versions.tools.rust = await commandStdoutOrNull("rustc --version"); + if (!ctx.versions.tools.rust) { + throw new Error("Rust is not installed!"); + } }, + exitOnError: false, }, { title: "Check cargo", task: async (ctx) => { ctx.versions.tools.cargo = await commandStdoutOrNull("cargo -V"); + if (!ctx.versions.tools.cargo) { + throw new Error("Cargo is not installed!"); + } }, + exitOnError: false, }, { title: "Check cargo nightly", task: async (ctx) => { ctx.versions.tools.cargoNightly = await commandStdoutOrNull("cargo +nightly -V"); + if (!ctx.versions.tools.cargoNightly) { + throw new Error("Cargo nightly is not installed!"); + } }, + exitOnError: false, }, { title: "Check cargo dylint", task: async (ctx) => { ctx.versions.tools.cargoDylint = await commandStdoutOrNull("cargo dylint -V"); + if (!ctx.versions.tools.cargoDylint) { + throw new Error("Cargo dylint is not installed!"); + } }, + exitOnError: false, }, { title: "Check cargo-contract", task: async (ctx) => { ctx.versions.tools.cargoContract = await commandStdoutOrNull("cargo contract -V"); + if (!ctx.versions.tools.cargoContract) { + throw new Error("Cargo contract is not installed!"); + } + const regex = /cargo-contract-contract (.*)-unknown-(.*)/; + const match = ctx.versions.tools.cargoContract.match(regex); + if (match) { + ctx.versions.tools.cargoContract = match[1]; + } else { + throw new Error("Cargo contract version not found!"); + } }, + exitOnError: false, }, { title: "Check swanky node", task: async (ctx) => { ctx.versions.node = this.swankyConfig.node.version !== "" ? this.swankyConfig.node.version : null; + if (!ctx.versions.node) { + throw new Error("Swanky node version not found in swanky.config.json"); + } }, + exitOnError: false, }, { title: "Read ink dependencies", @@ -120,28 +162,34 @@ export default class Check extends SwankyCommand { }, { title: "Verify ink version", + skip: (ctx): boolean => { + return !ctx.versions.tools.cargoContract; + }, task: async (ctx) => { let supportedInk = ctx.swankyConfig?.node.supportedInk; - const regex = /cargo-contract-contract (.*)-unknown-x86_64-unknown-linux-gnu/; - const cargoContract = ctx.versions.tools.cargoContract; - if (cargoContract) { - const match = cargoContract.match(regex); - if (match) { - const cargoVersion = match[1]; - const version = cargoContractDeps.get(cargoVersion); - if (version && semver.gt(supportedInk!, version[0])) { - supportedInk = version[0]; - } - } + const versions = cargoContractDeps.get(ctx.versions.tools.cargoContract!); + if (versions && semver.gt(versions[versions.length - 1], supportedInk!)) { + supportedInk = versions[0]; } + ctx.versions.supportedInk = supportedInk; + if (!supportedInk) { + throw new Error("Supported ink version not found in swanky.config.json"); + } + }, + exitOnError: false, + }, + { + title: "Verify ink dependencies", + skip: (ctx) => !ctx.versions.supportedInk, + task: async (ctx) => { const mismatched: Record = {}; Object.entries(ctx.versions.contracts).forEach(([contract, inkPackages]) => { Object.entries(inkPackages).forEach(([inkPackage, version]) => { - if (semver.gt(version, supportedInk!)) { + if (semver.gt(version, ctx.versions.supportedInk!)) { mismatched[ `${contract}-${inkPackage}` - ] = `Version of ${inkPackage} (${version}) in ${contract} is higher than supported ink version (${supportedInk})`; + ] = `Version of ${inkPackage} (${version}) in ${contract} is higher than supported ink version (${ctx.versions.supportedInk})`; } if (!(version.startsWith("=") || version.startsWith("v"))) { @@ -151,7 +199,11 @@ export default class Check extends SwankyCommand { }); ctx.mismatchedVersions = mismatched; + if (Object.entries(mismatched).length > 0) { + throw new Error("Ink version mismatch"); + } }, + exitOnError: false, }, { title: "Check for missing tools", @@ -163,19 +215,22 @@ export default class Check extends SwankyCommand { } } ctx.versions.missingTools = missingTools; + if (Object.entries(missingTools).length > 0) { + throw new Error("Missing tools"); + } }, - } + exitOnError: false, + }, ]); - process.platform - process.arch + const context = await tasks.run({ os: { platform: "", architecture: "" }, - versions: {tools: {}, missingTools: [], contracts: {} }, + versions: { tools: {}, missingTools: [], contracts: {} }, looseDefinitionDetected: false, }); Object.values(context.mismatchedVersions as any).forEach((mismatch) => - console.error(`[ERROR] ${mismatch as string}`) + console.error(`[ERROR] ${mismatch as string}`), ); if (context.looseDefinitionDetected) { console.log(`\n[WARNING]Some of the ink dependencies do not have a fixed version. @@ -183,26 +238,19 @@ export default class Check extends SwankyCommand { Please use "=" to install a fixed version (Example: "=3.0.1") `); } - const supportedPlatforms = ["darwin", "linux"]; - const supportedArch = ["arm64", "x64"]; - - if (!supportedPlatforms.includes(context.os.platform)) { - console.error(`[ERROR] Platform ${context.os.platform} is not supported`); - } - if (!supportedArch.includes(context.os.architecture)) { - console.error(`[ERROR] Architecture ${context.os.architecture} is not supported`); - } - console.log(context.os, context.versions); + console.log(context.os); + console.log(context.versions); const filePath = flags.file ?? null; - if(filePath) { + if (filePath) { await this.spinner.runCommand(async () => { - writeJson(filePath, [context.os, context.versions], { spaces: 2 }) - }, `Writing output to file ${chalk.yellowBright(filePath)}`) + writeJson(filePath, [context.os, context.versions], { spaces: 2 }); + }, `Writing output to file ${chalk.yellowBright(filePath)}`); } } } + interface Dependency { version?: string; tag?: string; From 6dee48eb74e48625dc2000cc2cf31bee330c95e9 Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Tue, 30 Jan 2024 23:24:38 +0200 Subject: [PATCH 08/16] fix: Correct check UX --- src/commands/check/index.ts | 146 +++++++++++++++++++---------------- src/commands/node/install.ts | 10 +-- src/lib/cargoContractInfo.ts | 22 +++--- 3 files changed, 96 insertions(+), 82 deletions(-) diff --git a/src/commands/check/index.ts b/src/commands/check/index.ts index ace7f2e8..241a705b 100644 --- a/src/commands/check/index.ts +++ b/src/commands/check/index.ts @@ -9,7 +9,9 @@ import semver from "semver"; import { SwankyCommand } from "../../lib/swankyCommand.js"; import { Flags } from "@oclif/core"; import chalk from "chalk"; -import { cargoContractDeps } from "../../lib/cargoContractInfo.js"; +import { CARGO_CONTRACT_INK_DEPS } from "../../lib/cargoContractInfo.js"; +import { CLIError } from "@oclif/core/lib/errors/index.js"; +import Warn = CLIError.Warn; interface Ctx { os: { @@ -27,7 +29,7 @@ interface Ctx { supportedInk?: string; missingTools: string[]; contracts: Record>; - node?: string | null; + swankyNode: string | null; }; swankyConfig?: SwankyConfig; mismatchedVersions?: Record; @@ -38,8 +40,8 @@ export default class Check extends SwankyCommand { static description = "Check installed package versions and compatibility"; static flags = { - file: Flags.string({ - char: "f", + print: Flags.string({ + char: "p", description: "File to write output to", }), }; @@ -49,85 +51,82 @@ export default class Check extends SwankyCommand { const tasks = new Listr([ { title: "Check OS", - task: async (ctx) => { + task: async (ctx, task) => { ctx.os.platform = process.platform; ctx.os.architecture = process.arch; const supportedPlatforms = ["darwin", "linux"]; const supportedArch = ["arm64", "x64"]; if (!supportedPlatforms.includes(ctx.os.platform)) { - throw new Error(`Platform ${ctx.os.platform} is not supported!`); + throw new Warn(`Platform ${ctx.os.platform} is not supported!`); } if (!supportedArch.includes(ctx.os.architecture)) { - throw new Error(`Architecture ${ctx.os.architecture} is not supported!`); + throw new Warn(`Architecture ${ctx.os.architecture} is not supported!`); } + + task.title = `Check OS: '${ctx.os.platform}-${ctx.os.architecture}'`; }, exitOnError: false, }, { title: "Check Rust", - task: async (ctx) => { - ctx.versions.tools.rust = await commandStdoutOrNull("rustc --version"); + task: async (ctx, task) => { + ctx.versions.tools.rust = (await commandStdoutOrNull("rustc --version"))?.match(/rustc (.*) \((.*)/)?.[1]; if (!ctx.versions.tools.rust) { - throw new Error("Rust is not installed!"); + throw new Warn("Rust is not installed!"); } + task.title = `Check Rust: ${ctx.versions.tools.rust}`; }, exitOnError: false, }, { title: "Check cargo", - task: async (ctx) => { - ctx.versions.tools.cargo = await commandStdoutOrNull("cargo -V"); + task: async (ctx, task) => { + ctx.versions.tools.cargo = (await commandStdoutOrNull("cargo -V"))?.match(/cargo (.*) \((.*)/)?.[1]; if (!ctx.versions.tools.cargo) { - throw new Error("Cargo is not installed!"); + throw new Warn("Cargo is not installed!"); } + task.title = `Check cargo: ${ctx.versions.tools.cargo}`; }, exitOnError: false, }, { title: "Check cargo nightly", - task: async (ctx) => { - ctx.versions.tools.cargoNightly = await commandStdoutOrNull("cargo +nightly -V"); + task: async (ctx, task) => { + ctx.versions.tools.cargoNightly = (await commandStdoutOrNull("cargo +nightly -V"))?.match(/cargo (.*)-nightly \((.*)/)?.[1]; if (!ctx.versions.tools.cargoNightly) { - throw new Error("Cargo nightly is not installed!"); + throw new Warn("Cargo nightly is not installed!"); } + task.title = `Check cargo nightly: ${ctx.versions.tools.cargoNightly}`; }, exitOnError: false, }, { title: "Check cargo dylint", - task: async (ctx) => { - ctx.versions.tools.cargoDylint = await commandStdoutOrNull("cargo dylint -V"); + task: async (ctx, task) => { + ctx.versions.tools.cargoDylint = (await commandStdoutOrNull("cargo dylint -V"))?.match(/cargo-dylint (.*)/)?.[1]; if (!ctx.versions.tools.cargoDylint) { - throw new Error("Cargo dylint is not installed!"); + throw new Warn("Cargo dylint is not installed!"); } + task.title = `Check cargo dylint: ${ctx.versions.tools.cargoDylint}`; }, exitOnError: false, }, { title: "Check cargo-contract", - task: async (ctx) => { + task: async (ctx, task) => { ctx.versions.tools.cargoContract = await commandStdoutOrNull("cargo contract -V"); if (!ctx.versions.tools.cargoContract) { - throw new Error("Cargo contract is not installed!"); + throw new Warn("Cargo contract is not installed!"); } - const regex = /cargo-contract-contract (.*)-unknown-(.*)/; + const regex = /cargo-contract-contract (.*)-unknown-(.*)-unknown-(.*)/; const match = ctx.versions.tools.cargoContract.match(regex); if (match) { ctx.versions.tools.cargoContract = match[1]; } else { - throw new Error("Cargo contract version not found!"); - } - }, - exitOnError: false, - }, - { - title: "Check swanky node", - task: async (ctx) => { - ctx.versions.node = this.swankyConfig.node.version !== "" ? this.swankyConfig.node.version : null; - if (!ctx.versions.node) { - throw new Error("Swanky node version not found in swanky.config.json"); + throw new Warn("Cargo contract version not found!"); } + task.title = `Check cargo-contract: ${ctx.versions.tools.cargoContract}`; }, exitOnError: false, }, @@ -162,45 +161,56 @@ export default class Check extends SwankyCommand { }, { title: "Verify ink version", - skip: (ctx): boolean => { - return !ctx.versions.tools.cargoContract; - }, + skip: (ctx) => !ctx.swankyConfig?.node?.version, task: async (ctx) => { - let supportedInk = ctx.swankyConfig?.node.supportedInk; - const versions = cargoContractDeps.get(ctx.versions.tools.cargoContract!); - if (versions && semver.gt(versions[versions.length - 1], supportedInk!)) { - supportedInk = versions[0]; - } + const supportedInk = ctx.swankyConfig!.node.supportedInk; + const mismatched: Record = {}; + Object.entries(ctx.versions.contracts).forEach(([contract, inkPackages]) => { + Object.entries(inkPackages).forEach(([inkPackage, version]) => { + if (semver.gt(version, supportedInk)) { + mismatched[ + `${contract}-${inkPackage}` + ] = `Version of ${inkPackage} (${version}) in ${contract} is higher than supported ink version (${supportedInk})`; + } - ctx.versions.supportedInk = supportedInk; - if (!supportedInk) { - throw new Error("Supported ink version not found in swanky.config.json"); + if (version.startsWith(">") || version.startsWith("<") || version.startsWith("^") || version.startsWith("~")) { + ctx.looseDefinitionDetected = true; + } + }); + }); + + ctx.mismatchedVersions = mismatched; + if (Object.entries(mismatched).length > 0) { + throw new Warn("Ink version mismatch"); } }, exitOnError: false, }, { - title: "Verify ink dependencies", - skip: (ctx) => !ctx.versions.supportedInk, + title: "Verify cargo-contract version", + skip: (ctx) => ctx.versions.tools.cargoContract === null, task: async (ctx) => { + const cargoContractVersion = ctx.versions.tools.cargoContract!.replace(/-.*$/, ""); + const compatibleInkVersion = CARGO_CONTRACT_INK_DEPS.find(dep => + semver.satisfies(cargoContractVersion, `>=${dep.minCargoContractVersion}`), + )?.inkVersion; + if (!compatibleInkVersion) { + throw new Warn(`cargo-contract version ${cargoContractVersion} is not supported`); + } const mismatched: Record = {}; Object.entries(ctx.versions.contracts).forEach(([contract, inkPackages]) => { Object.entries(inkPackages).forEach(([inkPackage, version]) => { - if (semver.gt(version, ctx.versions.supportedInk!)) { + if (semver.gt(version, compatibleInkVersion)) { mismatched[ `${contract}-${inkPackage}` - ] = `Version of ${inkPackage} (${version}) in ${contract} is higher than supported ink version (${ctx.versions.supportedInk})`; - } - - if (!(version.startsWith("=") || version.startsWith("v"))) { - ctx.looseDefinitionDetected = true; + ] = `Version of ${inkPackage} (${version}) in ${contract} is higher than compatible ink version (${compatibleInkVersion})`; } }); }); - ctx.mismatchedVersions = mismatched; + ctx.mismatchedVersions = { ...ctx.mismatchedVersions, ...mismatched }; if (Object.entries(mismatched).length > 0) { - throw new Error("Ink version mismatch"); + throw new Warn("cargo-contract version mismatch"); } }, exitOnError: false, @@ -212,11 +222,12 @@ export default class Check extends SwankyCommand { for (const [toolName, toolVersion] of Object.entries(ctx.versions.tools)) { if (!toolVersion) { missingTools.push(toolName); + console.error(`[ERROR] ${toolName} is not installed!`); } } ctx.versions.missingTools = missingTools; if (Object.entries(missingTools).length > 0) { - throw new Error("Missing tools"); + throw new Warn("Missing tools"); } }, exitOnError: false, @@ -225,13 +236,14 @@ export default class Check extends SwankyCommand { const context = await tasks.run({ os: { platform: "", architecture: "" }, - versions: { tools: {}, missingTools: [], contracts: {} }, + versions: { tools: {}, missingTools: [], contracts: {}, swankyNode: this.swankyConfig.node.version }, looseDefinitionDetected: false, }); - - Object.values(context.mismatchedVersions as any).forEach((mismatch) => - console.error(`[ERROR] ${mismatch as string}`), - ); + if (context.mismatchedVersions !== undefined) { + Object.values(context.mismatchedVersions).forEach((mismatch) => + console.error(`[ERROR] ${mismatch}`), + ); + } if (context.looseDefinitionDetected) { console.log(`\n[WARNING]Some of the ink dependencies do not have a fixed version. This can lead to accidentally installing version higher than supported by the node. @@ -239,13 +251,17 @@ export default class Check extends SwankyCommand { `); } - console.log(context.os); - console.log(context.versions); + const output = { + ...context.os, + ...context.versions + } + + console.log(output); - const filePath = flags.file ?? null; - if (filePath) { + const filePath = flags.print; + if (filePath !== undefined) { await this.spinner.runCommand(async () => { - writeJson(filePath, [context.os, context.versions], { spaces: 2 }); + writeJson(filePath, output, { spaces: 2 }); }, `Writing output to file ${chalk.yellowBright(filePath)}`); } } diff --git a/src/commands/node/install.ts b/src/commands/node/install.ts index 58c50cdf..cce8f24d 100644 --- a/src/commands/node/install.ts +++ b/src/commands/node/install.ts @@ -1,11 +1,11 @@ import { SwankyCommand } from "../../lib/swankyCommand.js"; -import { ux, Flags } from "@oclif/core"; +import { Flags } from "@oclif/core"; import { downloadNode, swankyNode } from "../../lib/index.js"; import path from "node:path"; import { writeJSON } from "fs-extra/esm"; import inquirer from "inquirer"; import { DEFAULT_NODE_INFO } from "../../lib/consts.js"; -import { pickNodeVersion } from "../../lib/prompts.js"; +import { choice, pickNodeVersion } from "../../lib/prompts.js"; export class InstallNode extends SwankyCommand { static description = "Install swanky node binary"; @@ -37,9 +37,9 @@ export class InstallNode extends SwankyCommand { const projectPath = path.resolve(); if (this.swankyConfig.node.localPath !== "") { - const overwrite = await ux.confirm( - "Swanky node already installed. Do you want to overwrite it? (y/n)" - ); + const { overwrite } =await inquirer.prompt([ + choice("overwrite", "Swanky node already installed. Do you want to overwrite it?"), + ]); if (!overwrite) { return; } diff --git a/src/lib/cargoContractInfo.ts b/src/lib/cargoContractInfo.ts index 8db616d3..844bca0a 100644 --- a/src/lib/cargoContractInfo.ts +++ b/src/lib/cargoContractInfo.ts @@ -1,12 +1,10 @@ -export type cargoContractInfo = typeof cargoContractDeps; - -export const cargoContractDeps = new Map([ - ["3.2.0", - ["4.0.0-alpha.3", "4.0.0"]], - ["4.0.0-alpha", - ["5.0.0-alpha", "5.0.0"]], - ["4.0.0-rc", - ["5.0.0-alpha", "5.0.0"]], - ["4.0.0-rc.1", - ["5.0.0-alpha", "5.0.0"]] -]); +export interface CargoContractInkDependency { + minCargoContractVersion: string; + inkVersion: string; +} +export const CARGO_CONTRACT_INK_DEPS: CargoContractInkDependency[] = [ + { minCargoContractVersion: "4.0.0", inkVersion: "5.0.0" }, + { minCargoContractVersion: "2.2.0", inkVersion: "4.2.0" }, + { minCargoContractVersion: "2.0.2", inkVersion: "4.0.1" }, + { minCargoContractVersion: "2.0.0", inkVersion: "4.0.0" }, +]; From 227d934b106f21d6efcb56578993983d612001a7 Mon Sep 17 00:00:00 2001 From: Igor Papandinas Date: Wed, 31 Jan 2024 13:59:23 +0100 Subject: [PATCH 09/16] fix: cargo-contrcact verification fixed --- src/commands/check/index.ts | 25 ++++++++++++++++--------- src/lib/cargoContractInfo.ts | 15 +++++++++------ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/commands/check/index.ts b/src/commands/check/index.ts index 241a705b..99bd3b35 100644 --- a/src/commands/check/index.ts +++ b/src/commands/check/index.ts @@ -188,22 +188,29 @@ export default class Check extends SwankyCommand { }, { title: "Verify cargo-contract version", - skip: (ctx) => ctx.versions.tools.cargoContract === null, + skip: (ctx) => !ctx.versions.tools.cargoContract, task: async (ctx) => { - const cargoContractVersion = ctx.versions.tools.cargoContract!.replace(/-.*$/, ""); - const compatibleInkVersion = CARGO_CONTRACT_INK_DEPS.find(dep => - semver.satisfies(cargoContractVersion, `>=${dep.minCargoContractVersion}`), - )?.inkVersion; - if (!compatibleInkVersion) { + const cargoContractVersion = ctx.versions.tools.cargoContract!; + const dependencyIdx = CARGO_CONTRACT_INK_DEPS.findIndex((dep) => + semver.satisfies(cargoContractVersion.replace(/-.*$/, ""), `>=${dep.minCargoContractVersion}`) + ); + + if (dependencyIdx === -1) { throw new Warn(`cargo-contract version ${cargoContractVersion} is not supported`); } + + const validInkVersionRange = CARGO_CONTRACT_INK_DEPS[dependencyIdx].validInkVersionRange; + const minCargoContractVersion = dependencyIdx === 0 + ? CARGO_CONTRACT_INK_DEPS[dependencyIdx].minCargoContractVersion + : CARGO_CONTRACT_INK_DEPS[dependencyIdx - 1].minCargoContractVersion + const mismatched: Record = {}; Object.entries(ctx.versions.contracts).forEach(([contract, inkPackages]) => { Object.entries(inkPackages).forEach(([inkPackage, version]) => { - if (semver.gt(version, compatibleInkVersion)) { + if (!semver.satisfies(version, validInkVersionRange)) { mismatched[ - `${contract}-${inkPackage}` - ] = `Version of ${inkPackage} (${version}) in ${contract} is higher than compatible ink version (${compatibleInkVersion})`; + `${contract} contract` + ] = `Version of ${inkPackage} (${version}) in ${contract} requires cargo-contract version >=${minCargoContractVersion}, but version ${cargoContractVersion} is installed`; } }); }); diff --git a/src/lib/cargoContractInfo.ts b/src/lib/cargoContractInfo.ts index 844bca0a..eafdd57d 100644 --- a/src/lib/cargoContractInfo.ts +++ b/src/lib/cargoContractInfo.ts @@ -1,10 +1,13 @@ export interface CargoContractInkDependency { minCargoContractVersion: string; - inkVersion: string; + validInkVersionRange: string; } + +// Keep cargo-contract versions in descending order +// Ranges are supported by semver export const CARGO_CONTRACT_INK_DEPS: CargoContractInkDependency[] = [ - { minCargoContractVersion: "4.0.0", inkVersion: "5.0.0" }, - { minCargoContractVersion: "2.2.0", inkVersion: "4.2.0" }, - { minCargoContractVersion: "2.0.2", inkVersion: "4.0.1" }, - { minCargoContractVersion: "2.0.0", inkVersion: "4.0.0" }, -]; + { minCargoContractVersion: "4.0.0", validInkVersionRange: "<99.0.0" }, // Non-max version known yet: a very high version is used as fallback in the meantime + { minCargoContractVersion: "2.2.0", validInkVersionRange: "<5.0.0" }, + { minCargoContractVersion: "2.0.2", validInkVersionRange: "<4.2.0" }, + { minCargoContractVersion: "2.0.0", validInkVersionRange: "<4.0.1" }, +]; \ No newline at end of file From b68bcc6a6afc6696d26ab400a6e42367baa6d8f8 Mon Sep 17 00:00:00 2001 From: Igor Papandinas Date: Wed, 31 Jan 2024 14:00:46 +0100 Subject: [PATCH 10/16] fix: cargo-contrcat regex fixed --- src/commands/check/index.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/commands/check/index.ts b/src/commands/check/index.ts index 99bd3b35..06eb2ecb 100644 --- a/src/commands/check/index.ts +++ b/src/commands/check/index.ts @@ -119,9 +119,10 @@ export default class Check extends SwankyCommand { if (!ctx.versions.tools.cargoContract) { throw new Warn("Cargo contract is not installed!"); } - const regex = /cargo-contract-contract (.*)-unknown-(.*)-unknown-(.*)/; + + const regex = /cargo-contract-contract (\d+\.\d+\.\d+(?:-[\w.]+)?)(?:-unknown-[\w-]+)/; const match = ctx.versions.tools.cargoContract.match(regex); - if (match) { + if (match?.[1]) { ctx.versions.tools.cargoContract = match[1]; } else { throw new Warn("Cargo contract version not found!"); From 0c7af46324105b7136b514ac650fdd4c0564c1a7 Mon Sep 17 00:00:00 2001 From: Igor Papandinas Date: Wed, 31 Jan 2024 14:18:45 +0100 Subject: [PATCH 11/16] fix: Ensure sanky node is installed and contracts exist for some tasks --- src/commands/check/index.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/commands/check/index.ts b/src/commands/check/index.ts index 06eb2ecb..deb9f368 100644 --- a/src/commands/check/index.ts +++ b/src/commands/check/index.ts @@ -48,6 +48,8 @@ export default class Check extends SwankyCommand { public async run(): Promise { const { flags } = await this.parse(Check); + const isSwankyNodeInstalled = !!this.swankyConfig?.node?.version; + const anyContracts = Object.keys(this.swankyConfig?.contracts).length > 0; const tasks = new Listr([ { title: "Check OS", @@ -133,6 +135,7 @@ export default class Check extends SwankyCommand { }, { title: "Read ink dependencies", + enabled: anyContracts, task: async (ctx) => { const swankyConfig = await readJSON("swanky.config.json"); ctx.swankyConfig = swankyConfig; @@ -161,8 +164,9 @@ export default class Check extends SwankyCommand { }, }, { - title: "Verify ink version", - skip: (ctx) => !ctx.swankyConfig?.node?.version, + title: "Verify ink version compatibility with Swanky node", + skip: (ctx) => Object.keys(ctx.versions.contracts).length === 0, + enabled: anyContracts && isSwankyNodeInstalled, task: async (ctx) => { const supportedInk = ctx.swankyConfig!.node.supportedInk; const mismatched: Record = {}; @@ -190,6 +194,7 @@ export default class Check extends SwankyCommand { { title: "Verify cargo-contract version", skip: (ctx) => !ctx.versions.tools.cargoContract, + enabled: anyContracts, task: async (ctx) => { const cargoContractVersion = ctx.versions.tools.cargoContract!; const dependencyIdx = CARGO_CONTRACT_INK_DEPS.findIndex((dep) => From 4cc4aa9588fba3a7affc95410dee54a34bb2dc66 Mon Sep 17 00:00:00 2001 From: Igor Papandinas Date: Wed, 31 Jan 2024 16:56:46 +0100 Subject: [PATCH 12/16] fix: Improve logging and outputs --- src/commands/check/index.ts | 56 ++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/commands/check/index.ts b/src/commands/check/index.ts index deb9f368..de14998a 100644 --- a/src/commands/check/index.ts +++ b/src/commands/check/index.ts @@ -32,7 +32,7 @@ interface Ctx { swankyNode: string | null; }; swankyConfig?: SwankyConfig; - mismatchedVersions?: Record; + mismatchedVersions: Record; looseDefinitionDetected: boolean; } @@ -48,7 +48,8 @@ export default class Check extends SwankyCommand { public async run(): Promise { const { flags } = await this.parse(Check); - const isSwankyNodeInstalled = !!this.swankyConfig?.node?.version; + const swankyNodeVersion = this.swankyConfig.node.version; + const isSwankyNodeInstalled = !!swankyNodeVersion; const anyContracts = Object.keys(this.swankyConfig?.contracts).length > 0; const tasks = new Listr([ { @@ -60,10 +61,10 @@ export default class Check extends SwankyCommand { const supportedArch = ["arm64", "x64"]; if (!supportedPlatforms.includes(ctx.os.platform)) { - throw new Warn(`Platform ${ctx.os.platform} is not supported!`); + throw new Error(`Platform ${ctx.os.platform} is not supported`); } if (!supportedArch.includes(ctx.os.architecture)) { - throw new Warn(`Architecture ${ctx.os.architecture} is not supported!`); + throw new Error(`Architecture ${ctx.os.architecture} is not supported`); } task.title = `Check OS: '${ctx.os.platform}-${ctx.os.architecture}'`; @@ -75,7 +76,7 @@ export default class Check extends SwankyCommand { task: async (ctx, task) => { ctx.versions.tools.rust = (await commandStdoutOrNull("rustc --version"))?.match(/rustc (.*) \((.*)/)?.[1]; if (!ctx.versions.tools.rust) { - throw new Warn("Rust is not installed!"); + throw new Error("Rust is not installed"); } task.title = `Check Rust: ${ctx.versions.tools.rust}`; }, @@ -86,7 +87,7 @@ export default class Check extends SwankyCommand { task: async (ctx, task) => { ctx.versions.tools.cargo = (await commandStdoutOrNull("cargo -V"))?.match(/cargo (.*) \((.*)/)?.[1]; if (!ctx.versions.tools.cargo) { - throw new Warn("Cargo is not installed!"); + throw new Error("Cargo is not installed"); } task.title = `Check cargo: ${ctx.versions.tools.cargo}`; }, @@ -97,7 +98,7 @@ export default class Check extends SwankyCommand { task: async (ctx, task) => { ctx.versions.tools.cargoNightly = (await commandStdoutOrNull("cargo +nightly -V"))?.match(/cargo (.*)-nightly \((.*)/)?.[1]; if (!ctx.versions.tools.cargoNightly) { - throw new Warn("Cargo nightly is not installed!"); + throw new Error("Cargo nightly is not installed"); } task.title = `Check cargo nightly: ${ctx.versions.tools.cargoNightly}`; }, @@ -108,7 +109,7 @@ export default class Check extends SwankyCommand { task: async (ctx, task) => { ctx.versions.tools.cargoDylint = (await commandStdoutOrNull("cargo dylint -V"))?.match(/cargo-dylint (.*)/)?.[1]; if (!ctx.versions.tools.cargoDylint) { - throw new Warn("Cargo dylint is not installed!"); + throw new Warn("Cargo dylint is not installed"); } task.title = `Check cargo dylint: ${ctx.versions.tools.cargoDylint}`; }, @@ -119,7 +120,7 @@ export default class Check extends SwankyCommand { task: async (ctx, task) => { ctx.versions.tools.cargoContract = await commandStdoutOrNull("cargo contract -V"); if (!ctx.versions.tools.cargoContract) { - throw new Warn("Cargo contract is not installed!"); + throw new Error("Cargo contract is not installed"); } const regex = /cargo-contract-contract (\d+\.\d+\.\d+(?:-[\w.]+)?)(?:-unknown-[\w-]+)/; @@ -127,7 +128,7 @@ export default class Check extends SwankyCommand { if (match?.[1]) { ctx.versions.tools.cargoContract = match[1]; } else { - throw new Warn("Cargo contract version not found!"); + throw new Error("Cargo contract version not found"); } task.title = `Check cargo-contract: ${ctx.versions.tools.cargoContract}`; }, @@ -175,7 +176,7 @@ export default class Check extends SwankyCommand { if (semver.gt(version, supportedInk)) { mismatched[ `${contract}-${inkPackage}` - ] = `Version of ${inkPackage} (${version}) in ${contract} is higher than supported ink version (${supportedInk})`; + ] = `Version of ${inkPackage} (${version}) in ${chalk.yellowBright(contract)} is higher than supported ink version (${supportedInk}) in current Swanky node version (${swankyNodeVersion}). A Swanky node update can fix this warning.`; } if (version.startsWith(">") || version.startsWith("<") || version.startsWith("^") || version.startsWith("~")) { @@ -186,13 +187,13 @@ export default class Check extends SwankyCommand { ctx.mismatchedVersions = mismatched; if (Object.entries(mismatched).length > 0) { - throw new Warn("Ink version mismatch"); + throw new Warn("Ink versions in contracts don't match the Swanky node's supported version."); } }, exitOnError: false, }, { - title: "Verify cargo-contract version", + title: "Verify cargo contract compatibility", skip: (ctx) => !ctx.versions.tools.cargoContract, enabled: anyContracts, task: async (ctx) => { @@ -215,8 +216,8 @@ export default class Check extends SwankyCommand { Object.entries(inkPackages).forEach(([inkPackage, version]) => { if (!semver.satisfies(version, validInkVersionRange)) { mismatched[ - `${contract} contract` - ] = `Version of ${inkPackage} (${version}) in ${contract} requires cargo-contract version >=${minCargoContractVersion}, but version ${cargoContractVersion} is installed`; + `${contract}-${inkPackage}` + ] = `Version of ${inkPackage} (${version}) in ${chalk.yellowBright(contract)} requires cargo-contract version >=${minCargoContractVersion}, but version ${cargoContractVersion} is installed`; } }); }); @@ -235,12 +236,13 @@ export default class Check extends SwankyCommand { for (const [toolName, toolVersion] of Object.entries(ctx.versions.tools)) { if (!toolVersion) { missingTools.push(toolName); - console.error(`[ERROR] ${toolName} is not installed!`); + if (toolName === "cargoDylint") this.warn("Cargo dylint is not installed"); + else this.error(`${toolName} is not installed`); } } ctx.versions.missingTools = missingTools; if (Object.entries(missingTools).length > 0) { - throw new Warn("Missing tools"); + throw new Warn(`Missing tools: ${missingTools.join(", ")}`); } }, exitOnError: false, @@ -249,16 +251,20 @@ export default class Check extends SwankyCommand { const context = await tasks.run({ os: { platform: "", architecture: "" }, - versions: { tools: {}, missingTools: [], contracts: {}, swankyNode: this.swankyConfig.node.version }, + versions: { + tools: {}, + missingTools: [], + contracts: {}, + swankyNode: swankyNodeVersion || null, + }, looseDefinitionDetected: false, + mismatchedVersions: {} }); - if (context.mismatchedVersions !== undefined) { - Object.values(context.mismatchedVersions).forEach((mismatch) => - console.error(`[ERROR] ${mismatch}`), - ); - } + + Object.values(context.mismatchedVersions).forEach((mismatch) => this.warn(mismatch)); + if (context.looseDefinitionDetected) { - console.log(`\n[WARNING]Some of the ink dependencies do not have a fixed version. + this.warn(`Some of the ink dependencies do not have a fixed version. This can lead to accidentally installing version higher than supported by the node. Please use "=" to install a fixed version (Example: "=3.0.1") `); @@ -269,8 +275,6 @@ export default class Check extends SwankyCommand { ...context.versions } - console.log(output); - const filePath = flags.print; if (filePath !== undefined) { await this.spinner.runCommand(async () => { From 4b59279ac39bcfd0d7c99d9b6e35eb20682c314c Mon Sep 17 00:00:00 2001 From: Igor Papandinas Date: Wed, 31 Jan 2024 17:50:59 +0100 Subject: [PATCH 13/16] fix: CI --- src/commands/node/install.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/node/install.ts b/src/commands/node/install.ts index f705b1f4..79beab3e 100644 --- a/src/commands/node/install.ts +++ b/src/commands/node/install.ts @@ -1,6 +1,6 @@ import { SwankyCommand } from "../../lib/swankyCommand.js"; import { Flags } from "@oclif/core"; -import { downloadNode, swankyNode } from "../../lib/index.js"; +import { downloadNode, swankyNodeVersions } from "../../lib/index.js"; import path from "node:path"; import { writeJSON } from "fs-extra/esm"; import inquirer from "inquirer"; From 9756a9f4ff86dfbaeb040d87d3934e9fe149f35f Mon Sep 17 00:00:00 2001 From: Igor Papandinas Date: Wed, 31 Jan 2024 18:03:37 +0100 Subject: [PATCH 14/16] chore: Bump supported ink version for swanky node 1.6.0 --- README.md | 2 +- src/lib/nodeInfo.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 51a6b4e4..6d707795 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ A newly generated project will have a `swanky.config.json` file that will get po "node": { "localPath": "/Users/sasapul/Work/astar/swanky-cli/temp_proj/bin/swanky-node", "polkadotPalletVersions": "polkadot-v0.9.39", - "supportedInk": "v4.2.0" + "supportedInk": "v4.3.0" }, "accounts": [ { diff --git a/src/lib/nodeInfo.ts b/src/lib/nodeInfo.ts index 60a6d1f0..59e2f415 100644 --- a/src/lib/nodeInfo.ts +++ b/src/lib/nodeInfo.ts @@ -18,7 +18,7 @@ export const swankyNodeVersions = new Map([ ["1.6.0", { version: "1.6.0", polkadotPalletVersions: "polkadot-v0.9.39", - supportedInk: "v4.2.0", + supportedInk: "v4.3.0", downloadUrl: { darwin: { "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-macOS-universal.tar.gz", From 20ad6ed2c4055db72db24247cd7867c48f67d98b Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Wed, 7 Feb 2024 20:10:24 +0200 Subject: [PATCH 15/16] fix: More common chat for print flag --- src/commands/check/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/check/index.ts b/src/commands/check/index.ts index de14998a..a8604e95 100644 --- a/src/commands/check/index.ts +++ b/src/commands/check/index.ts @@ -41,7 +41,7 @@ export default class Check extends SwankyCommand { static flags = { print: Flags.string({ - char: "p", + char: "o", description: "File to write output to", }), }; From c86d83fbec6e24ec38cbc1580079d9e890907632 Mon Sep 17 00:00:00 2001 From: Igor Papandinas Date: Mon, 12 Feb 2024 11:56:38 +0100 Subject: [PATCH 16/16] fix: build --- src/commands/check/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/check/index.ts b/src/commands/check/index.ts index 50bfc0ed..ce45afe9 100644 --- a/src/commands/check/index.ts +++ b/src/commands/check/index.ts @@ -137,7 +137,7 @@ export default class Check extends SwankyCommand { { title: "Check swanky node", task: async (ctx) => { - ctx.versions.node = this.swankyConfig.node.version !== "" ? this.swankyConfig.node.version : null; + ctx.versions.swankyNode = this.swankyConfig.node.version !== "" ? this.swankyConfig.node.version : null; }, }, {