Skip to content

Commit 7b5b93b

Browse files
feat(kadena-cli): add devnet commands to kadena-cli
1 parent 6065963 commit 7b5b93b

19 files changed

+977
-14
lines changed

.changeset/tough-rabbits-poke.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@kadena/kadena-cli': patch
3+
---
4+
5+
add devnet commands to kadena-cli

packages/tools/kadena-cli/src/config/commands/configInit.ts

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ export const createConfigInitCommand: (
1616
await import('../../networks/init.js');
1717
console.log(chalk.green('Configured default networks.'));
1818

19+
await import('../../devnet/init.js');
20+
console.log(chalk.green('Configured default devnets.'));
21+
1922
console.log(chalk.green('Configuration complete!'));
2023
},
2124
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import type { IDevnetsCreateOptions } from '../devnet/utils/devnetHelpers.js';
2+
3+
export interface IDefaultDevnetOptions {
4+
[key: string]: IDevnetsCreateOptions;
5+
}
6+
7+
/**
8+
* @const devnetDefaults
9+
* Provides the default devnet configurations.
10+
*/
11+
export const devnetDefaults: IDefaultDevnetOptions = {
12+
devnet: {
13+
name: 'devnet',
14+
port: 8080,
15+
useVolume: false,
16+
mountPactFolder: '',
17+
version: 'latest',
18+
},
19+
};
20+
21+
export const defaultDevnetsPath: string = `${process.cwd()}/.kadena/devnets`;
22+
export const standardDevnets: string[] = ['devnet'];
23+
export const defaultDevnet: string = 'devnet';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { defaultDevnetsPath } from '../../constants/devnets.js';
2+
import { ensureFileExists } from '../../utils/filesystem.js';
3+
import { writeDevnet } from '../utils/devnetHelpers.js';
4+
5+
import debug from 'debug';
6+
import path from 'path';
7+
8+
import chalk from 'chalk';
9+
import { devnetOverwritePrompt } from '../../prompts/devnet.js';
10+
import { createExternalPrompt } from '../../prompts/generic.js';
11+
import { createCommand } from '../../utils/createCommand.js';
12+
import { globalOptions } from '../../utils/globalOptions.js';
13+
14+
export const createDevnetCommand = createCommand(
15+
'create',
16+
'Create devnet',
17+
[
18+
globalOptions.devnetName(),
19+
globalOptions.devnetPort(),
20+
globalOptions.devnetUseVolume(),
21+
globalOptions.devnetMountPactFolder(),
22+
globalOptions.devnetVersion(),
23+
],
24+
async (config) => {
25+
debug('devnet-create:action')({ config });
26+
27+
const filePath = path.join(defaultDevnetsPath, `${config.name}.yaml`);
28+
29+
if (ensureFileExists(filePath)) {
30+
const externalPrompt = createExternalPrompt({
31+
devnetOverwritePrompt,
32+
});
33+
const overwrite = await externalPrompt.devnetOverwritePrompt();
34+
if (overwrite === 'no') {
35+
console.log(
36+
chalk.yellow(
37+
`\nThe existing devnet configuration "${config.name}" will not be updated.\n`,
38+
),
39+
);
40+
return;
41+
}
42+
}
43+
44+
writeDevnet(config);
45+
46+
console.log(
47+
chalk.green(
48+
`\nThe devnet configuration "${config.name}" has been saved.\n`,
49+
),
50+
);
51+
},
52+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import debug from 'debug';
2+
import { devnetDeletePrompt } from '../../prompts/devnet.js';
3+
import { globalOptions } from '../../utils/globalOptions.js';
4+
import {
5+
getDevnetConfiguration,
6+
removeDevnetConfiguration,
7+
} from '../utils/devnetHelpers.js';
8+
9+
import chalk from 'chalk';
10+
import { createExternalPrompt } from '../../prompts/generic.js';
11+
import { createCommand } from '../../utils/createCommand.js';
12+
import {
13+
dockerVolumeName,
14+
isDockerInstalled,
15+
removeDevnet,
16+
removeVolume,
17+
} from '../utils/docker.js';
18+
19+
export const deleteDevnetCommand = createCommand(
20+
'delete',
21+
'Delete devnet',
22+
[globalOptions.devnetSelect()],
23+
async (config) => {
24+
debug('devnet-delete:action')({ config });
25+
26+
const externalPrompt = createExternalPrompt({
27+
devnetDeletePrompt,
28+
});
29+
const deleteDevnet = await externalPrompt.devnetDeletePrompt();
30+
31+
if (deleteDevnet === 'no') {
32+
console.log(
33+
chalk.yellow(
34+
`\nThe devnet configuration "${config.name}" will not be deleted.\n`,
35+
),
36+
);
37+
return;
38+
}
39+
40+
if (!isDockerInstalled()) {
41+
console.log(
42+
chalk.red(
43+
'Stopping devnet requires Docker. Please install Docker and try again.',
44+
),
45+
);
46+
return;
47+
}
48+
49+
removeDevnet(config.name);
50+
console.log(chalk.green(`Removed devnet container: ${config.name}`));
51+
52+
const configuration = getDevnetConfiguration(config.name);
53+
54+
if (configuration?.useVolume) {
55+
removeVolume(config.name);
56+
console.log(
57+
chalk.green(`Removed volume: ${dockerVolumeName(config.name)}`),
58+
);
59+
}
60+
61+
console.log(
62+
chalk.green(
63+
`Successfully removed devnet container for configuration: ${config.name}`,
64+
),
65+
);
66+
67+
removeDevnetConfiguration(config);
68+
69+
console.log(
70+
chalk.green(`Successfully removed devnet configuration: ${config.name}`),
71+
);
72+
},
73+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import debug from 'debug';
2+
import { createCommand } from '../../utils/createCommand.js';
3+
import { displayDevnetsConfig } from '../utils/devnetDisplay.js';
4+
5+
export const listDevnetsCommand = createCommand(
6+
'list',
7+
'List all available devnets',
8+
[],
9+
async (config) => {
10+
debug('devnet-list:action')({ config });
11+
12+
await displayDevnetsConfig();
13+
},
14+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import debug from 'debug';
2+
import { devnetOverwritePrompt } from '../../prompts/devnet.js';
3+
import { globalOptions } from '../../utils/globalOptions.js';
4+
import { writeDevnet } from '../utils/devnetHelpers.js';
5+
6+
import chalk from 'chalk';
7+
import { createExternalPrompt } from '../../prompts/generic.js';
8+
import { createCommand } from '../../utils/createCommand.js';
9+
10+
export const manageDevnetsCommand = createCommand(
11+
'manage',
12+
'Manage devnets',
13+
[
14+
globalOptions.devnetSelect(),
15+
globalOptions.devnetPort(),
16+
globalOptions.devnetUseVolume(),
17+
globalOptions.devnetMountPactFolder(),
18+
globalOptions.devnetVersion(),
19+
],
20+
async (config) => {
21+
debug('devnet-manage:action')({ config });
22+
23+
const externalPrompt = createExternalPrompt({
24+
devnetOverwritePrompt,
25+
});
26+
const overwrite = await externalPrompt.devnetOverwritePrompt();
27+
28+
if (overwrite === 'no') {
29+
console.log(
30+
chalk.yellow(
31+
`\nThe devnet configuration "${config.name}" will not be updated.\n`,
32+
),
33+
);
34+
return;
35+
}
36+
37+
writeDevnet(config);
38+
39+
console.log(
40+
chalk.green(
41+
`\nThe devnet configuration "${config.name}" has been updated.\n`,
42+
),
43+
);
44+
},
45+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import debug from 'debug';
2+
import { globalOptions } from '../../utils/globalOptions.js';
3+
4+
import chalk from 'chalk';
5+
import { createCommand } from '../../utils/createCommand.js';
6+
import { isDockerInstalled, runDevnet } from '../utils/docker.js';
7+
8+
export const runDevnetCommand = createCommand(
9+
'run',
10+
'Run devnet',
11+
[globalOptions.devnet()],
12+
async (config) => {
13+
debug('devnet-run:action')({ config });
14+
15+
if (!isDockerInstalled()) {
16+
console.log(
17+
chalk.red(
18+
'Running devnet requires Docker. Please install Docker and try again.',
19+
),
20+
);
21+
return;
22+
}
23+
24+
runDevnet(config.devnetConfig);
25+
26+
console.log(
27+
chalk.green(
28+
`\nThe devnet configuration "${config.devnet}" is running.\n`,
29+
),
30+
);
31+
},
32+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import debug from 'debug';
2+
import { globalOptions } from '../../utils/globalOptions.js';
3+
4+
import chalk from 'chalk';
5+
import { createCommand } from '../../utils/createCommand.js';
6+
import { isDockerInstalled, stopDevnet } from '../utils/docker.js';
7+
8+
export const stopDevnetCommand = createCommand(
9+
'stop',
10+
'Stop devnet',
11+
[globalOptions.devnetSelect()],
12+
async (config) => {
13+
debug('devnet-stop:action')({ config });
14+
15+
if (!isDockerInstalled()) {
16+
console.log(
17+
chalk.red(
18+
'Stopping devnet requires Docker. Please install Docker and try again.',
19+
),
20+
);
21+
return;
22+
}
23+
24+
stopDevnet(config.name);
25+
26+
console.log(
27+
chalk.green(
28+
`\nThe devnet configuration "${config.name}" has been stopped.\n`,
29+
),
30+
);
31+
},
32+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import chalk from 'chalk';
2+
import debug from 'debug';
3+
import { createCommand } from '../../utils/createCommand.js';
4+
import { globalOptions } from '../../utils/globalOptions.js';
5+
import { isDockerInstalled, updateDevnet } from '../utils/docker.js';
6+
7+
export const updateDevnetCommand = createCommand(
8+
'update',
9+
'Update the Docker image of a given devnet container image',
10+
[globalOptions.devnetVersion()],
11+
async (config) => {
12+
debug('devnet-update:action')({ config });
13+
14+
// Abort if Docker is not installed
15+
if (!isDockerInstalled()) {
16+
console.log(
17+
chalk.red(
18+
'Updating devnet requires Docker. Please install Docker and try again.',
19+
),
20+
);
21+
return;
22+
}
23+
24+
updateDevnet(config.version || 'latest');
25+
},
26+
);

packages/tools/kadena-cli/src/devnet/commands/start.ts

-9
This file was deleted.
+16-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
1-
import { devnetStartCommand } from './commands/start.js';
1+
import { createDevnetCommand } from './commands/devnetCreate.js';
2+
import { deleteDevnetCommand } from './commands/devnetDelete.js';
3+
import { listDevnetsCommand } from './commands/devnetList.js';
4+
import { manageDevnetsCommand } from './commands/devnetManage.js';
5+
import { runDevnetCommand } from './commands/devnetRun.js';
6+
import { stopDevnetCommand } from './commands/devnetStop.js';
7+
import { updateDevnetCommand } from './commands/devnetUpdate.js';
28

39
import type { Command } from 'commander';
410

511
const SUBCOMMAND_ROOT: 'devnet' = 'devnet';
612

713
export function devnetCommandFactory(program: Command, version: string): void {
8-
const devnetProgram = program
14+
const devnetsProgram = program
915
.command(SUBCOMMAND_ROOT)
10-
.description(`Tool for starting, stopping and managing the local devnet`);
16+
.description(`Tool to create and manage devnets`);
1117

12-
devnetStartCommand(devnetProgram, version);
18+
listDevnetsCommand(devnetsProgram, version);
19+
manageDevnetsCommand(devnetsProgram, version);
20+
createDevnetCommand(devnetsProgram, version);
21+
deleteDevnetCommand(devnetsProgram, version);
22+
runDevnetCommand(devnetsProgram, version);
23+
stopDevnetCommand(devnetsProgram, version);
24+
updateDevnetCommand(devnetsProgram, version);
1325
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { devnetDefaults } from '../constants/devnets.js';
2+
import { writeDevnet } from './utils/devnetHelpers.js';
3+
4+
writeDevnet(devnetDefaults.devnet);

0 commit comments

Comments
 (0)