-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathruntime-env.ts
130 lines (106 loc) · 3.49 KB
/
runtime-env.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import { State } from "@devnet/state";
import { Config as OclifConfig } from "@oclif/core";
import { readFile, rm } from "node:fs/promises";
import * as YAML from "yaml";
import { assert } from "./assert.js";
import { FactoryResult } from "./command.js";
import { USER_CONFIG_PATH } from "./constants.js";
import { DevNetLogger } from "./logger.js";
import { DevNetDRENetwork } from "./network/index.js";
import { DevNetServiceRegistry } from "./service/service-registry.js";
export const loadUserConfig = async () =>
YAML.parse(await readFile(USER_CONFIG_PATH, "utf-8"));
export class DevNetRuntimeEnvironment {
public readonly logger: DevNetLogger;
public readonly network: DevNetDRENetwork;
public readonly services: DevNetServiceRegistry["services"];
public readonly state: State;
private readonly oclifConfig: OclifConfig;
private readonly registry: DevNetServiceRegistry;
constructor(
network: string,
rawConfig: unknown,
registry: DevNetServiceRegistry,
logger: DevNetLogger,
oclifConfig: OclifConfig,
) {
this.state = new State(
rawConfig,
registry.root,
registry.services.kurtosis.artifact.root,
);
this.network = new DevNetDRENetwork(network, this.state, logger);
this.services = registry.services;
this.registry = registry;
this.logger = logger;
this.oclifConfig = oclifConfig;
}
static async getNew(
network: string,
commandName: string,
oclifConfig: OclifConfig,
) {
const logger = new DevNetLogger(network, commandName);
const userConfig = await loadUserConfig().catch(() =>
console.log("User config not found, use empty object"),
);
const networkConfig =
userConfig?.networks?.find((net: any) => net?.name === network) ?? {};
const registry = await DevNetServiceRegistry.getNew(
network,
commandName,
logger,
);
const dre = new DevNetRuntimeEnvironment(
network,
networkConfig,
registry,
logger,
oclifConfig,
);
return dre;
}
public async clean() {
for (const service of Object.values(this.services)) {
// TODO: call destroy hook here
await service.artifact.clean();
}
await rm(this.registry.root, { recursive: true, force: true });
}
public clone(commandName: string) {
const newLogger = new DevNetLogger(this.network.name, commandName);
return new DevNetRuntimeEnvironment(
this.network.name,
this.state,
this.registry.clone(commandName, newLogger),
newLogger,
this.oclifConfig,
);
}
public runCommand<
F extends Record<string, any>,
CMD extends FactoryResult<F>,
>(cmd: CMD, args: CMD["_internalParams"]) {
return cmd.exec(this, args);
}
public async runHooks() {
for (const service of Object.values(this.registry.services)) {
for (const command of service.artifact.emittedCommands) {
await this.runCommandByString(command, service.config.name);
}
}
}
private async runCommandByString(commandName: string, invokedBy: string) {
const cmd = this.oclifConfig.findCommand(commandName);
assert(
cmd !== undefined,
`You have specified a command that does not exist, invoked by ${invokedBy}`,
);
const CommandClass = (await cmd.load()) as FactoryResult<any>;
assert(
CommandClass.exec !== undefined,
`You have specified a command that cannot be invoked with the string, invoked by ${invokedBy}`,
);
await CommandClass.exec(this.clone(commandName), {});
}
}