Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): configuration and channel support for the CLI #2145

Merged
merged 9 commits into from
Feb 25, 2019
7 changes: 5 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"publish:alpha": "npm publish --tag alpha",
"publish:beta": "npm publish --tag beta",
"publish:rc": "npm publish --tag rc",
"publish:stable": "npm publish --tag latest",
"publish:latest": "npm publish --tag latest",
"prepublishOnly": "yarn build",
"pretest": "yarn lint && yarn build",
"prepack": "oclif-dev manifest && npm shrinkwrap",
Expand Down Expand Up @@ -122,7 +122,10 @@
"oclif": {
"commands": "./dist/commands",
"hooks": {
"init": "./dist/hooks/init"
"init": [
"./dist/hooks/init/config",
"./dist/hooks/init/update"
]
},
"bin": "ark",
"topics": {
Expand Down
7 changes: 5 additions & 2 deletions packages/core/src/commands/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Listr from "listr";
import { join, resolve } from "path";
import pm2 from "pm2";
import prompts from "prompts";
import { configManager } from "../helpers/config";

// tslint:disable-next-line:no-var-requires
const { version } = require("../../package.json");
Expand All @@ -16,8 +17,6 @@ export abstract class BaseCommand extends Command {
public static flagsNetwork: Record<string, object> = {
token: flags.string({
description: "the name of the token that should be used",
default: "ark",
required: true,
}),
network: flags.string({
description: "the name of the network that should be used",
Expand Down Expand Up @@ -129,6 +128,10 @@ export abstract class BaseCommand extends Command {
protected async parseWithNetwork(command: any): Promise<any> {
const { args, flags } = this.parse(command);

if (!flags.token) {
flags.token = configManager.get("token");
}

if (process.env.CORE_PATH_CONFIG && !flags.network) {
let config: string = process.env.CORE_PATH_CONFIG;

Expand Down
66 changes: 66 additions & 0 deletions packages/core/src/commands/config/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { flags } from "@oclif/command";
import cli from "cli-ux";
import { removeSync } from "fs-extra";
import { configManager } from "../../helpers/config";
import { installFromChannel } from "../../helpers/update";
import { BaseCommand } from "../command";

export class CommandLineInterfaceCommand extends BaseCommand {
public static description: string = "Update the CLI configuration";

public static examples: string[] = [
`Set the token that should be used for configuration
$ ark config:cli --token=mine
`,
`Switch the npm registry channel
$ ark config:cli --channel=mine
`,
];

public static flags: Record<string, any> = {
token: flags.string({
description: "the name of the token that should be used",
}),
channel: flags.string({
description: "the name of the channel that should be used",
options: ["alpha", "beta", "rc", "latest"],
}),
};

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

if (flags.token) {
configManager.update({ token: flags.token });
}

if (flags.channel) {
this.changeChannel(flags.channel);
}
}

private async changeChannel(newChannel): Promise<void> {
const oldChannel = configManager.get("channel");

if (oldChannel === newChannel) {
this.warn(`You are already on the "${newChannel}" channel.`);
return;
}

configManager.update({ channel: newChannel });

const pkg = `${this.config.name}@${newChannel}`;

try {
cli.action.start(`Installing ${pkg}`);

await installFromChannel(this.config.name, newChannel);

cli.action.stop();

this.warn(`${pkg} has been installed. Please restart your relay and forger.`);
} catch (err) {
this.error(err.message);
}
}
}
5 changes: 5 additions & 0 deletions packages/core/src/commands/config/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { flags } from "@oclif/command";
import fs from "fs-extra";
import { resolve } from "path";
import prompts from "prompts";
import { configManager } from "../../helpers/config";
import { BaseCommand } from "../command";

export class PublishCommand extends BaseCommand {
Expand All @@ -20,6 +21,10 @@ $ ark config:publish --network=mainnet
public async run(): Promise<void> {
const { flags } = this.parse(PublishCommand);

if (!flags.token) {
flags.token = configManager.get("token");
}

if (flags.network) {
return this.performPublishment(flags);
}
Expand Down
48 changes: 48 additions & 0 deletions packages/core/src/helpers/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { existsSync } from "fs";
import { readJsonSync, removeSync, writeJsonSync } from "fs-extra";
import { getRegistryChannel } from "./update";

class ConfigManager {
private config;
private file: string;

public setup(config) {
this.config = config;
this.file = `${config.configDir}/config.json`;

try {
this.read();
} catch (error) {
removeSync(this.file);

this.ensureDefaults();
}
}

public get(key) {
return this.read()[key];
}

public update(data): void {
this.write({ ...this.read(), ...data });
}

private ensureDefaults(): void {
if (!existsSync(this.file)) {
this.write({
token: this.config.bin,
channel: getRegistryChannel(this.config),
});
}
}

private read() {
return readJsonSync(this.file);
}

private write(data): void {
writeJsonSync(this.file, data);
}
}

export const configManager = new ConfigManager();
27 changes: 15 additions & 12 deletions packages/core/src/helpers/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import latestVersion from "latest-version";
import { join } from "path";
import prompts from "prompts";
import semver from "semver";
import { configManager } from "./config";

async function getVersionFromNode(name: string, channel: string): Promise<string> {
try {
Expand All @@ -26,7 +27,7 @@ function ensureCacheFile(config: IConfig): string {
return join(config.cacheDir, "update");
}

function getUpdateChannel(config: IConfig): string {
export function getRegistryChannel(config: IConfig): string {
const channels: string[] = ["alpha", "beta", "rc"];

let channel: string = "latest";
Expand All @@ -52,6 +53,16 @@ export function needsRefresh(config: IConfig): boolean {
}
}

export async function installFromChannel(pkg, channel) {
const { stdout, stderr } = await shell(`yarn global add ${pkg}@${channel}`);

if (stderr) {
console.error(stderr);
}

console.log(stdout);
}

export async function checkForUpdates({ config, error, log, warn }): Promise<void> {
if (existsSync(join(__dirname, "../../../..", ".git"))) {
if (!process.env.CORE_DEVELOPER_MODE) {
Expand All @@ -61,7 +72,7 @@ export async function checkForUpdates({ config, error, log, warn }): Promise<voi
}

try {
const channel = getUpdateChannel(config);
const channel = configManager.get("channel");
const cacheFile = ensureCacheFile(config);

cli.action.start(`Checking for updates`);
Expand Down Expand Up @@ -90,24 +101,16 @@ export async function checkForUpdates({ config, error, log, warn }): Promise<voi
]);

if (response.confirm) {
cli.action.start(`Updating from ${config.version} to ${remoteVersion}`);

try {
const { stdout, stderr } = await shell(`yarn global add ${config.name}@${channel}`);
cli.action.start(`Updating from ${config.version} to ${remoteVersion}`);

if (stderr) {
console.error(stderr);
}

console.log(stdout);
await installFromChannel(config.name, channel);

removeSync(cacheFile);

cli.action.stop();

warn(`Version ${remoteVersion} has been installed. Please restart your relay and forger.`);

process.exit();
} catch (err) {
error(err.message);
}
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/hooks/init/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Hook } from "@oclif/config";
import { configManager } from "../../helpers/config";

// tslint:disable-next-line:only-arrow-functions
export const init: Hook<"init"> = async function({ config }) {
configManager.setup(config);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Hook } from "@oclif/config";
import { checkForUpdates, needsRefresh } from "../helpers/update";
import { checkForUpdates, needsRefresh } from "../../helpers/update";

// tslint:disable-next-line:only-arrow-functions
export const init: Hook<"init"> = async function({ id, config }) {
Expand Down