Skip to content

Commit

Permalink
feat(core-cli): read token and network from config.json (#4208)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastijankuzner authored Dec 4, 2020
1 parent 9eb1ce9 commit 49e89a8
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 56 deletions.
26 changes: 20 additions & 6 deletions __tests__/unit/core-cli/commands/command.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Container } from "@arkecosystem/core-cli";
import { Console } from "@arkecosystem/core-test-framework";
import Joi from "@hapi/joi";
import { Command } from "@packages/core-cli/src/commands";
import { Command, DiscoverConfig } from "@packages/core-cli/src/commands";
import { setGracefulCleanup } from "tmp";

@Container.injectable()
Expand Down Expand Up @@ -72,14 +72,14 @@ describe("Command", () => {
});

describe("#initialize", () => {
it("should initialize the command", () => {
expect(cmd.initialize()).resolves.toBeUndefined();
it("should initialize the command", async () => {
await expect(cmd.initialize()).resolves.toBeUndefined();
});
});

describe("#interact", () => {
it("should interact with the user", () => {
expect(cmd.interact()).resolves.toBeUndefined();
it("should interact with the user", async () => {
await expect(cmd.interact()).resolves.toBeUndefined();
});
});

Expand All @@ -97,6 +97,19 @@ describe("Command", () => {
await cmd.run();
});

it("should run the command without a network and token if network is detected from config", async () => {
const spyOnDiscover = jest.spyOn(DiscoverConfig.prototype, "discover").mockResolvedValue({
token: "token",
network: "testnet",
});

await cmd.run();

expect(spyOnDiscover).toHaveBeenCalledTimes(2);
expect(cmd.getFlag("token")).toEqual("token");
expect(cmd.getFlag("network")).toEqual("testnet");
});

it("should run the command in interactive mode", async () => {
cmd.register(["env:paths", "--interaction"]);

Expand Down Expand Up @@ -135,14 +148,15 @@ describe("Command", () => {

describe("#execute", () => {
it("should execute the command", async () => {
expect(cmd.execute()).resolves.toBeUndefined();
await expect(cmd.execute()).resolves.toBeUndefined();
});
});

describe("#showHelp", () => {
it("should display the help", () => {
let output;
jest.spyOn(cli.app.get(Container.Identifiers.Box), "render").mockImplementation(
// @ts-ignore
(message: string) => (output = message),
);

Expand Down
50 changes: 50 additions & 0 deletions __tests__/unit/core-cli/commands/discover-config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Console } from "@arkecosystem/core-test-framework";
import { DiscoverConfig } from "@packages/core-cli/src/commands";
import { ensureDirSync, writeJSON } from "fs-extra";
import { join } from "path";
import { dirSync, setGracefulCleanup } from "tmp";

let cli;
let cmd;
let configPath;
const config = { token: "token", network: "testnet" };

jest.mock("env-paths", () => () => ({
config: configPath,
}));

beforeAll(() => setGracefulCleanup());

beforeEach(() => {
cli = new Console();

cmd = cli.app.resolve(DiscoverConfig);

configPath = join(dirSync().name, "token-core");
});

describe("DiscoverConfig", () => {
it("should return undefined if configuration can't be found", async () => {
await expect(cmd.discover()).resolves.toEqual(undefined);
});

it("should return configuration if found on default config location", async () => {
ensureDirSync(join(configPath, "testnet"));

await writeJSON(join(configPath, "testnet", "config.json"), config);

await expect(cmd.discover("token", "testnet")).resolves.toEqual(config);
});

it("should return configuration if found on CORE_PATH_CONFIG location", async () => {
process.env.CORE_PATH_CONFIG = join(configPath, "testnet");

ensureDirSync(join(configPath, "testnet"));

await writeJSON(join(configPath, "testnet", "config.json"), config);

await expect(cmd.discover()).resolves.toEqual(config);

delete process.env.CORE_PATH_CONFIG;
});
});
43 changes: 8 additions & 35 deletions __tests__/unit/core-cli/commands/discover-network.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Console } from "@arkecosystem/core-test-framework";
import { DiscoverNetwork } from "@packages/core-cli/src/commands";
import envPaths from "env-paths";
import { ensureDirSync } from "fs-extra";
import prompts from "prompts";
import { dirSync, setGracefulCleanup } from "tmp";
Expand All @@ -16,74 +15,48 @@ beforeEach(() => {

cmd = cli.app.resolve(DiscoverNetwork);

configPath = envPaths("ark", { suffix: "core" }).config;
configPath = dirSync().name;
});

describe("DiscoverNetwork", () => {
it("should throw if no configurations can be detected", async () => {
await expect(cmd.discover(configPath)).rejects.toThrow();

delete process.env.CORE_PATH_CONFIG;
});

it("should throw if no configurations can be detected (with environment variable as path)", async () => {
process.env.CORE_PATH_CONFIG = dirSync().name;

await expect(cmd.discover(configPath)).rejects.toThrow();

delete process.env.CORE_PATH_CONFIG;
});

it("should choose the first network if only a single network is found", async () => {
process.env.CORE_PATH_CONFIG = dirSync().name;

ensureDirSync(`${process.env.CORE_PATH_CONFIG}/mainnet`);
ensureDirSync(`${configPath}/mainnet`);

await expect(cmd.discover(configPath)).resolves.toBe("mainnet");

delete process.env.CORE_PATH_CONFIG;
});

it("should throw if the given path does not exist", async () => {
await expect(cmd.discover("does-not-exist")).rejects.toThrow("The [does-not-exist] directory does not exist.");
});

it("should choose the selected network if multiple networks are found", async () => {
process.env.CORE_PATH_CONFIG = dirSync().name;

ensureDirSync(`${process.env.CORE_PATH_CONFIG}/mainnet`);
ensureDirSync(`${process.env.CORE_PATH_CONFIG}/devnet`);
ensureDirSync(`${configPath}/mainnet`);
ensureDirSync(`${configPath}/devnet`);

prompts.inject(["devnet", true]);

await expect(cmd.discover(configPath)).resolves.toBe("devnet");

delete process.env.CORE_PATH_CONFIG;
});

it("should throw if the network selection is not confirmed", async () => {
process.env.CORE_PATH_CONFIG = dirSync().name;

ensureDirSync(`${process.env.CORE_PATH_CONFIG}/mainnet`);
ensureDirSync(`${process.env.CORE_PATH_CONFIG}/devnet`);
ensureDirSync(`${configPath}/mainnet`);
ensureDirSync(`${configPath}/devnet`);

prompts.inject(["devnet", false]);

await expect(cmd.discover(configPath)).rejects.toThrow("You'll need to confirm the network to continue.");

delete process.env.CORE_PATH_CONFIG;
});

it("should throw if the network selection is not valid", async () => {
process.env.CORE_PATH_CONFIG = dirSync().name;

ensureDirSync(`${process.env.CORE_PATH_CONFIG}/mainnet`);
ensureDirSync(`${process.env.CORE_PATH_CONFIG}/devnet`);
ensureDirSync(`${configPath}/mainnet`);
ensureDirSync(`${configPath}/devnet`);

prompts.inject(["randomnet", true]);

await expect(cmd.discover(configPath)).rejects.toThrow(`The given network "randomnet" is not valid.`);

delete process.env.CORE_PATH_CONFIG;
});
});
17 changes: 17 additions & 0 deletions packages/core-cli/src/commands/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Identifiers, inject, injectable, postConstruct } from "../ioc";
import { Output } from "../output";
import { Config, Environment } from "../services";
import { CommandHelp } from "./command-help";
import { DiscoverConfig } from "./discover-config";
import { DiscoverNetwork } from "./discover-network";

/**
Expand Down Expand Up @@ -183,10 +184,15 @@ export abstract class Command {
*/
public async run(): Promise<void> {
try {
await this.detectConfig();

if (this.requiresNetwork) {
await this.detectNetwork();
}

// Check for configuration again after network was chosen
await this.detectConfig();

if (this.input.hasFlag("token") && this.input.hasFlag("network")) {
this.app
.rebind(Identifiers.ApplicationPaths)
Expand Down Expand Up @@ -284,6 +290,17 @@ export abstract class Command {
return this.input.hasFlag(name);
}

private async detectConfig(): Promise<void> {
const config = await this.app
.resolve(DiscoverConfig)
.discover(this.input.getFlag("token"), this.input.getFlag("network"));

if (config) {
this.input.setFlag("token", config.token);
this.input.setFlag("network", config.network);
}
}

/**
* @private
* @returns {Promise<void>}
Expand Down
35 changes: 35 additions & 0 deletions packages/core-cli/src/commands/discover-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import envPaths from "env-paths";
import { readJSON } from "fs-extra";
import { join } from "path";

import { injectable } from "../ioc";

interface Config {
token: string;
network: string;
}

/**
* @export
* @class DiscoverNetwork
*/
@injectable()
export class DiscoverConfig {
/**
* @returns {Promise<string>}
* @memberof DiscoverNetwork
* @param token
* @param network
*/
public async discover(token: string = "", network: string = ""): Promise<Config | undefined> {
try {
return await readJSON(join(process.env.CORE_PATH_CONFIG!, "config.json"));
} catch {}

try {
return await readJSON(join(envPaths(token, { suffix: "core" }).config, network, "config.json"));
} catch {}

return undefined;
}
}
4 changes: 0 additions & 4 deletions packages/core-cli/src/commands/discover-network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ export class DiscoverNetwork {
* @memberof DiscoverNetwork
*/
public async discover(path: string): Promise<string> {
if (process.env.CORE_PATH_CONFIG) {
path = process.env.CORE_PATH_CONFIG;
}

if (!existsSync(path)) {
throw new Error(`The [${path}] directory does not exist.`);
}
Expand Down
1 change: 1 addition & 0 deletions packages/core-cli/src/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./command-help";
export * from "./command";
export * from "./discover-commands";
export * from "./discover-config";
export * from "./discover-network";
4 changes: 4 additions & 0 deletions packages/core/bin/config/devnet/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"token": "ark",
"network": "devnet"
}
4 changes: 4 additions & 0 deletions packages/core/bin/config/mainnet/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"token": "ark",
"network": "mainnet"
}
4 changes: 4 additions & 0 deletions packages/core/bin/config/testnet/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"token": "ark",
"network": "testnet"
}
22 changes: 11 additions & 11 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@
"debug:forger": "node --inspect-brk yarn ark forger:run",
"debug:relay": "node --inspect-brk yarn ark relay:run",
"debug:start": "node --inspect-brk yarn ark core:run",
"core:devnet": "cross-env CORE_PATH_CONFIG=./bin/config/devnet yarn ark core:run --network=devnet",
"core:mainnet": "cross-env CORE_PATH_CONFIG=./bin/config/mainnet yarn ark core:run --network=mainnet",
"core:testnet": "cross-env CORE_PATH_CONFIG=./bin/config/testnet yarn ark core:run --env=test --network=testnet",
"relay:devnet": "cross-env CORE_PATH_CONFIG=./bin/config/devnet yarn ark relay:run --network=devnet",
"relay:mainnet": "cross-env CORE_PATH_CONFIG=./bin/config/mainnet yarn ark relay:run --network=mainnet",
"relay:testnet": "cross-env CORE_PATH_CONFIG=./bin/config/testnet yarn ark relay:run --env=test --network=testnet",
"forger:devnet": "cross-env CORE_PATH_CONFIG=./bin/config/devnet yarn ark forger:run --network=devnet",
"forger:mainnet": "cross-env CORE_PATH_CONFIG=./bin/config/mainnet yarn ark forger:run --network=mainnet",
"forger:testnet": "cross-env CORE_PATH_CONFIG=./bin/config/testnet yarn ark forger:run --env=test --network=testnet",
"full:testnet": "cross-env CORE_PATH_CONFIG=./bin/config/testnet yarn ark core:run --networkStart --env=test --network=testnet",
"manager:testnet": "cross-env CORE_PATH_CONFIG=./bin/config/testnet yarn ark manager:run --env=test --network=testnet",
"core:devnet": "cross-env CORE_PATH_CONFIG=./bin/config/devnet yarn ark core:run",
"core:mainnet": "cross-env CORE_PATH_CONFIG=./bin/config/mainnet yarn ark core:run",
"core:testnet": "cross-env CORE_PATH_CONFIG=./bin/config/testnet yarn ark core:run --env=test",
"relay:devnet": "cross-env CORE_PATH_CONFIG=./bin/config/devnet yarn ark relay:run",
"relay:mainnet": "cross-env CORE_PATH_CONFIG=./bin/config/mainnet yarn ark relay:run",
"relay:testnet": "cross-env CORE_PATH_CONFIG=./bin/config/testnet yarn ark relay:run --env=test",
"forger:devnet": "cross-env CORE_PATH_CONFIG=./bin/config/devnet yarn ark forger:run",
"forger:mainnet": "cross-env CORE_PATH_CONFIG=./bin/config/mainnet yarn ark forger:run",
"forger:testnet": "cross-env CORE_PATH_CONFIG=./bin/config/testnet yarn ark forger:run --env=test",
"full:testnet": "cross-env CORE_PATH_CONFIG=./bin/config/testnet yarn ark core:run --networkStart",
"manager:testnet": "cross-env CORE_PATH_CONFIG=./bin/config/testnet yarn ark manager:run --env=test",
"prepublishOnly": "yarn build"
},
"dependencies": {
Expand Down

0 comments on commit 49e89a8

Please sign in to comment.