Skip to content

Commit

Permalink
feat: Integrate Zombienet for XCM development and testing (#66)
Browse files Browse the repository at this point in the history
Co-authored-by: Igor Papandinas <igor.papandinas@posteo.net>
  • Loading branch information
prxgr4mm3r and ipapandinas authored Feb 27, 2024
1 parent e315716 commit f6e32e5
Show file tree
Hide file tree
Showing 13 changed files with 534 additions and 12 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"ora": "6.3.1",
"semver": "7.5.4",
"shelljs": "0.8.5",
"toml": "^3.0.0",
"ts-mocha": "^10.0.0",
"winston": "^3.10.0"
},
Expand Down
2 changes: 1 addition & 1 deletion src/commands/init/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ export class Init extends SwankyCommand<typeof Init> {
callback(result as string);
}
}
this.log("🎉 😎 Swanky project successfully initialised! 😎 🎉");
this.log("🎉 😎 Swanky project successfully initialized! 😎 🎉");
}

async generate(projectName: string) {
Expand Down
105 changes: 105 additions & 0 deletions src/commands/zombienet/init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import path from "node:path";
import { Flags } from "@oclif/core";
import { SwankyCommand } from "../../lib/swankyCommand.js";
import {
buildZombienetConfigFromBinaries,
copyZombienetTemplateFile,
downloadZombienetBinaries,
getSwankyConfig,
getTemplates,
osCheck,
Spinner,
} from "../../lib/index.js";
import { pathExistsSync } from "fs-extra/esm";
import { zombienet, zombienetBinariesList } from "../../lib/zombienetInfo.js";
import { ConfigBuilder } from "../../lib/config-builder.js";
import { SwankyConfig, ZombienetData } from "../../index.js";

export const zombienetConfig = "zombienet.config.toml";

export class InitZombienet extends SwankyCommand<typeof InitZombienet> {
static description = "Initialize Zombienet";

static flags = {
binaries: Flags.string({
char: "b",
multiple: true,
required: false,
options: zombienetBinariesList,
default: [],
description: "Binaries to install",
}),
};

async run(): Promise<void> {
const { flags } = await this.parse(InitZombienet);

const localConfig = getSwankyConfig("local") as SwankyConfig;

const platform = osCheck().platform;
if (platform === "darwin") {
this.warn(`Note for MacOs users: Polkadot binary is not currently supported for MacOs.
As a result users of MacOS need to clone the Polkadot repo (https://github.com/paritytech/polkadot), create a release and add it in your PATH manually (setup will advice you so as well). Check the official zombienet documentation for manual settings: https://paritytech.github.io/zombienet/.`);
}

const projectPath = path.resolve();
if (pathExistsSync(path.resolve(projectPath, "zombienet", "bin", "zombienet"))) {
this.error("Zombienet config already initialized");
}

const spinner = new Spinner(flags.verbose);

const zombienetData: ZombienetData = {
version: zombienet.version,
downloadUrl: zombienet.downloadUrl,
binaries: {},
};

if (!flags.binaries.includes("polkadot")) {
flags.binaries.push("polkadot");
}

for (const binaryName of flags.binaries) {
if (platform === "darwin" && binaryName.startsWith("polkadot")) {
continue;
}
if (!Object.keys(zombienet.binaries).includes(binaryName)) {
this.error(`Binary ${binaryName} not found in Zombienet config`);
}
zombienetData.binaries[binaryName] = zombienet.binaries[binaryName as keyof typeof zombienet.binaries];
}

await this.spinner.runCommand(async () => {
const newLocalConfig = new ConfigBuilder(localConfig)
.addZombienet(zombienetData)
.build();
await this.storeConfig(newLocalConfig, "local");
}, "Writing config");

const zombienetTemplatePath = getTemplates().zombienetTemplatesPath;

const configPath = path.resolve(projectPath, "zombienet", "config");

if (flags.binaries.length === 1 && flags.binaries[0] === "polkadot") {
await spinner.runCommand(
() =>
copyZombienetTemplateFile(zombienetTemplatePath, configPath),
"Copying template files",
);
} else {
await spinner.runCommand(
() => buildZombienetConfigFromBinaries(flags.binaries, zombienetTemplatePath, configPath),
"Copying template files",
);
}

// Install binaries based on zombie config
await this.spinner.runCommand(
() => downloadZombienetBinaries(flags.binaries, projectPath, localConfig, this.spinner),
"Downloading Zombienet binaries",
);

this.log("ZombieNet config Installed successfully");
}
}

40 changes: 40 additions & 0 deletions src/commands/zombienet/start.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { SwankyCommand } from "../../lib/swankyCommand.js";
import path from "node:path";
import { pathExistsSync } from "fs-extra/esm";
import { execaCommand } from "execa";
import { Flags } from "@oclif/core";


export class StartZombienet extends SwankyCommand<typeof StartZombienet> {
static description = "Start Zombienet";

static flags = {
"config-path": Flags.string({
char: "c",
required: false,
default: "./zombienet/config/zombienet.config.toml",
description: "Path to zombienet config",
}),
};

async run(): Promise<void> {
const { flags } = await this.parse(StartZombienet);
const projectPath = path.resolve();
const binPath = path.resolve(projectPath, "zombienet", "bin")
if (!pathExistsSync(path.resolve(binPath, "zombienet"))) {
this.error("Zombienet has not initialized. Run `swanky zombienet:init` first");
}

await execaCommand(
`./zombienet/bin/zombienet \
spawn --provider native \
${flags["config-path"]}
`,
{
stdio: "inherit",
}
);

this.log("ZombieNet started successfully");
}
}
9 changes: 8 additions & 1 deletion src/lib/config-builder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AccountData, BuildData, DeploymentData, SwankyConfig, SwankySystemConfig } from "../index.js";
import { AccountData, BuildData, DeploymentData, SwankyConfig, SwankySystemConfig, ZombienetData } from "../index.js";
import { snakeCase } from "change-case";

export class ConfigBuilder<T extends SwankySystemConfig | SwankyConfig> {
Expand Down Expand Up @@ -64,6 +64,13 @@ export class ConfigBuilder<T extends SwankySystemConfig | SwankyConfig> {
return this;
}

addZombienet(data: ZombienetData): ConfigBuilder<T> {
if ("zombienet" in this.config) {
this.config.zombienet = data;
}
return this;
}

build(): T {
return this.config;
}
Expand Down
Loading

0 comments on commit f6e32e5

Please sign in to comment.