genlayer 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.js +14 -3
- package/docker-compose.yml +6 -1
- package/package.json +1 -1
- package/src/commands/general/init.ts +5 -4
- package/src/lib/interfaces/ISimulatorService.ts +1 -0
- package/src/lib/services/simulator.ts +12 -0
- package/tests/actions/init.test.ts +7 -2
- package/tests/services/simulator.test.ts +40 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.24.0 (2025-07-16)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* Add Docker Volume Cleanup to Init Flow ([#240](https://github.com/yeagerai/genlayer-cli/issues/240)) ([e61b82c](https://github.com/yeagerai/genlayer-cli/commit/e61b82c3d31aa71860eccad510141cd3f932e4aa))
|
|
8
|
+
|
|
3
9
|
## 0.23.0 (2025-07-15)
|
|
4
10
|
|
|
5
11
|
### Features
|
package/dist/index.js
CHANGED
|
@@ -17856,7 +17856,7 @@ var require_semver2 = __commonJS({
|
|
|
17856
17856
|
import { program } from "commander";
|
|
17857
17857
|
|
|
17858
17858
|
// package.json
|
|
17859
|
-
var version = "0.
|
|
17859
|
+
var version = "0.24.0";
|
|
17860
17860
|
var package_default = {
|
|
17861
17861
|
name: "genlayer",
|
|
17862
17862
|
version,
|
|
@@ -41939,6 +41939,16 @@ Run npm install -g genlayer to update
|
|
|
41939
41939
|
await image.remove({ force: true });
|
|
41940
41940
|
}
|
|
41941
41941
|
}
|
|
41942
|
+
async resetDockerVolumes() {
|
|
41943
|
+
const volumes = await this.docker.listVolumes();
|
|
41944
|
+
const genlayerVolumes = volumes.Volumes?.filter(
|
|
41945
|
+
(volume) => volume.Name.startsWith("genlayer_")
|
|
41946
|
+
) || [];
|
|
41947
|
+
for (const volumeInfo of genlayerVolumes) {
|
|
41948
|
+
const volume = this.docker.getVolume(volumeInfo.Name);
|
|
41949
|
+
await volume.remove({ force: true });
|
|
41950
|
+
}
|
|
41951
|
+
}
|
|
41942
41952
|
async cleanDatabase() {
|
|
41943
41953
|
try {
|
|
41944
41954
|
await rpcClient.request({ method: "sim_clearDbTables", params: [["current_state", "transactions"]] });
|
|
@@ -42038,12 +42048,13 @@ var InitAction = class extends BaseAction {
|
|
|
42038
42048
|
return;
|
|
42039
42049
|
}
|
|
42040
42050
|
this.stopSpinner();
|
|
42041
|
-
const confirmMessage = isRunning ? `GenLayer Localnet is already running and this command is going to reset GenLayer docker images and
|
|
42051
|
+
const confirmMessage = isRunning ? `GenLayer Localnet is already running and this command is going to reset GenLayer docker images, containers and volumes, providers API Keys, and GenLayer database (accounts, transactions, validators and logs). Contract code (gpy files) will be kept. Do you want to continue?` : `This command is going to reset GenLayer docker images, containers and volumes, providers API Keys, and GenLayer database (accounts, transactions, validators and logs). Contract code (gpy files) will be kept. Do you want to continue?`;
|
|
42042
42052
|
await this.confirmPrompt(confirmMessage);
|
|
42043
42053
|
this.logInfo(`Initializing GenLayer CLI with ${options.numValidators} validators`);
|
|
42044
|
-
this.startSpinner("Resetting Docker containers and
|
|
42054
|
+
this.startSpinner("Resetting Docker containers, images, and volumes...");
|
|
42045
42055
|
await this.simulatorService.resetDockerContainers();
|
|
42046
42056
|
await this.simulatorService.resetDockerImages();
|
|
42057
|
+
await this.simulatorService.resetDockerVolumes();
|
|
42047
42058
|
this.stopSpinner();
|
|
42048
42059
|
const llmQuestions = [
|
|
42049
42060
|
{
|
package/docker-compose.yml
CHANGED
|
@@ -143,7 +143,12 @@ services:
|
|
|
143
143
|
volumes:
|
|
144
144
|
- hardhat_artifacts:/app/artifacts
|
|
145
145
|
- hardhat_deployments:/app/deployments
|
|
146
|
+
- hardhat_cache:/app/cache
|
|
147
|
+
- hardhat_snapshots:/app/snapshots
|
|
146
148
|
|
|
147
149
|
volumes:
|
|
148
150
|
hardhat_artifacts:
|
|
149
|
-
hardhat_deployments:
|
|
151
|
+
hardhat_deployments:
|
|
152
|
+
hardhat_cache:
|
|
153
|
+
hardhat_snapshots:
|
|
154
|
+
|
package/package.json
CHANGED
|
@@ -76,17 +76,18 @@ export class InitAction extends BaseAction {
|
|
|
76
76
|
this.stopSpinner();
|
|
77
77
|
|
|
78
78
|
const confirmMessage = isRunning
|
|
79
|
-
? `GenLayer Localnet is already running and this command is going to reset GenLayer docker images and
|
|
80
|
-
: `This command is going to reset GenLayer docker images and
|
|
79
|
+
? `GenLayer Localnet is already running and this command is going to reset GenLayer docker images, containers and volumes, providers API Keys, and GenLayer database (accounts, transactions, validators and logs). Contract code (gpy files) will be kept. Do you want to continue?`
|
|
80
|
+
: `This command is going to reset GenLayer docker images, containers and volumes, providers API Keys, and GenLayer database (accounts, transactions, validators and logs). Contract code (gpy files) will be kept. Do you want to continue?`;
|
|
81
81
|
|
|
82
82
|
await this.confirmPrompt(confirmMessage);
|
|
83
83
|
|
|
84
84
|
this.logInfo(`Initializing GenLayer CLI with ${options.numValidators} validators`);
|
|
85
85
|
|
|
86
|
-
// Reset Docker containers and
|
|
87
|
-
this.startSpinner("Resetting Docker containers and
|
|
86
|
+
// Reset Docker containers, images, and volumes
|
|
87
|
+
this.startSpinner("Resetting Docker containers, images, and volumes...");
|
|
88
88
|
await this.simulatorService.resetDockerContainers();
|
|
89
89
|
await this.simulatorService.resetDockerImages();
|
|
90
|
+
await this.simulatorService.resetDockerVolumes();
|
|
90
91
|
this.stopSpinner();
|
|
91
92
|
|
|
92
93
|
const llmQuestions: DistinctQuestion[] = [
|
|
@@ -15,6 +15,7 @@ export interface ISimulatorService {
|
|
|
15
15
|
stopDockerContainers(): Promise<void>;
|
|
16
16
|
resetDockerContainers(): Promise<void>;
|
|
17
17
|
resetDockerImages(): Promise<void>;
|
|
18
|
+
resetDockerVolumes(): Promise<void>;
|
|
18
19
|
checkCliVersion(): Promise<void>;
|
|
19
20
|
cleanDatabase(): Promise<boolean>;
|
|
20
21
|
addConfigToEnvFile(newConfig: Record<string, string>): void;
|
|
@@ -278,6 +278,18 @@ export class SimulatorService implements ISimulatorService {
|
|
|
278
278
|
}
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
+
public async resetDockerVolumes(): Promise<void> {
|
|
282
|
+
const volumes = await this.docker.listVolumes();
|
|
283
|
+
const genlayerVolumes = volumes.Volumes?.filter(volume =>
|
|
284
|
+
volume.Name.startsWith('genlayer_')
|
|
285
|
+
) || [];
|
|
286
|
+
|
|
287
|
+
for (const volumeInfo of genlayerVolumes) {
|
|
288
|
+
const volume = this.docker.getVolume(volumeInfo.Name);
|
|
289
|
+
await volume.remove({force: true});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
281
293
|
public async cleanDatabase(): Promise<boolean> {
|
|
282
294
|
|
|
283
295
|
try {
|
|
@@ -13,6 +13,7 @@ describe("InitAction", () => {
|
|
|
13
13
|
let checkVersionRequirementsSpy: ReturnType<typeof vi.spyOn>;
|
|
14
14
|
let resetDockerContainersSpy: ReturnType<typeof vi.spyOn>;
|
|
15
15
|
let resetDockerImagesSpy: ReturnType<typeof vi.spyOn>;
|
|
16
|
+
let resetDockerVolumesSpy: ReturnType<typeof vi.spyOn>;
|
|
16
17
|
let addConfigToEnvFileSpy: ReturnType<typeof vi.spyOn>;
|
|
17
18
|
let runSimulatorSpy: ReturnType<typeof vi.spyOn>;
|
|
18
19
|
let waitForSimulatorSpy: ReturnType<typeof vi.spyOn>;
|
|
@@ -57,6 +58,9 @@ describe("InitAction", () => {
|
|
|
57
58
|
resetDockerImagesSpy = vi
|
|
58
59
|
.spyOn(SimulatorService.prototype, "resetDockerImages")
|
|
59
60
|
.mockResolvedValue(undefined);
|
|
61
|
+
resetDockerVolumesSpy = vi
|
|
62
|
+
.spyOn(SimulatorService.prototype, "resetDockerVolumes")
|
|
63
|
+
.mockResolvedValue(undefined);
|
|
60
64
|
addConfigToEnvFileSpy = vi.spyOn(SimulatorService.prototype, "addConfigToEnvFile").mockResolvedValue();
|
|
61
65
|
runSimulatorSpy = vi
|
|
62
66
|
.spyOn(SimulatorService.prototype, "runSimulator")
|
|
@@ -98,7 +102,7 @@ describe("InitAction", () => {
|
|
|
98
102
|
await initAction.execute(defaultOptions);
|
|
99
103
|
|
|
100
104
|
expect(confirmPromptSpy).toHaveBeenCalledWith(
|
|
101
|
-
"GenLayer Localnet is already running and this command is going to reset GenLayer docker images and
|
|
105
|
+
"GenLayer Localnet is already running and this command is going to reset GenLayer docker images, containers and volumes, providers API Keys, and GenLayer database (accounts, transactions, validators and logs). Contract code (gpy files) will be kept. Do you want to continue?",
|
|
102
106
|
);
|
|
103
107
|
});
|
|
104
108
|
|
|
@@ -114,7 +118,7 @@ describe("InitAction", () => {
|
|
|
114
118
|
await initAction.execute(defaultOptions);
|
|
115
119
|
|
|
116
120
|
expect(confirmPromptSpy).toHaveBeenCalledWith(
|
|
117
|
-
"This command is going to reset GenLayer docker images and
|
|
121
|
+
"This command is going to reset GenLayer docker images, containers and volumes, providers API Keys, and GenLayer database (accounts, transactions, validators and logs). Contract code (gpy files) will be kept. Do you want to continue?",
|
|
118
122
|
);
|
|
119
123
|
});
|
|
120
124
|
|
|
@@ -130,6 +134,7 @@ describe("InitAction", () => {
|
|
|
130
134
|
expect(checkVersionRequirementsSpy).toHaveBeenCalled();
|
|
131
135
|
expect(resetDockerContainersSpy).toHaveBeenCalled();
|
|
132
136
|
expect(resetDockerImagesSpy).toHaveBeenCalled();
|
|
137
|
+
expect(resetDockerVolumesSpy).toHaveBeenCalled();
|
|
133
138
|
expect(addConfigToEnvFileSpy).toHaveBeenCalledWith({
|
|
134
139
|
OPENAIKEY: "API_KEY_OPENAI",
|
|
135
140
|
HEURISTAIAPIKEY: "API_KEY_HEURIST",
|
|
@@ -499,6 +499,46 @@ describe("SimulatorService - Docker Tests", () => {
|
|
|
499
499
|
expect(mockRemove).toHaveBeenCalledWith({force: true});
|
|
500
500
|
});
|
|
501
501
|
|
|
502
|
+
test("should remove Docker volumes with genlayer_ prefix", async () => {
|
|
503
|
+
const mockVolumes = {
|
|
504
|
+
Volumes: [
|
|
505
|
+
{ Name: "genlayer_volume1" },
|
|
506
|
+
{ Name: "genlayer_postgres" },
|
|
507
|
+
{ Name: "genlayer_data" },
|
|
508
|
+
{ Name: "unrelated_volume" },
|
|
509
|
+
{ Name: "another_volume" },
|
|
510
|
+
{ Name: "hardhat_artifacts" },
|
|
511
|
+
],
|
|
512
|
+
Warnings: [],
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
const mockListVolumes = vi.mocked(Docker.prototype.listVolumes);
|
|
516
|
+
const mockGetVolume = vi.mocked(Docker.prototype.getVolume);
|
|
517
|
+
|
|
518
|
+
mockListVolumes.mockResolvedValue(mockVolumes as any);
|
|
519
|
+
|
|
520
|
+
const mockRemove = vi.fn().mockResolvedValue(undefined);
|
|
521
|
+
mockGetVolume.mockImplementation(
|
|
522
|
+
() =>
|
|
523
|
+
({
|
|
524
|
+
remove: mockRemove,
|
|
525
|
+
}) as unknown as Docker.Volume,
|
|
526
|
+
);
|
|
527
|
+
|
|
528
|
+
const result = await simulatorService.resetDockerVolumes();
|
|
529
|
+
|
|
530
|
+
expect(result).toBe(undefined);
|
|
531
|
+
expect(mockListVolumes).toHaveBeenCalled();
|
|
532
|
+
expect(mockGetVolume).toHaveBeenCalledWith("genlayer_volume1");
|
|
533
|
+
expect(mockGetVolume).toHaveBeenCalledWith("genlayer_postgres");
|
|
534
|
+
expect(mockGetVolume).toHaveBeenCalledWith("genlayer_data");
|
|
535
|
+
expect(mockGetVolume).not.toHaveBeenCalledWith("unrelated_volume");
|
|
536
|
+
expect(mockGetVolume).not.toHaveBeenCalledWith("another_volume");
|
|
537
|
+
expect(mockGetVolume).not.toHaveBeenCalledWith("hardhat_artifacts");
|
|
538
|
+
expect(mockRemove).toHaveBeenCalledTimes(3);
|
|
539
|
+
expect(mockRemove).toHaveBeenCalledWith({force: true});
|
|
540
|
+
});
|
|
541
|
+
|
|
502
542
|
test("should execute command when docker is installed but is not available", async () => {
|
|
503
543
|
vi.mocked(checkCommand).mockResolvedValueOnce(undefined);
|
|
504
544
|
|