@cartesi/cli 2.0.0-alpha.15 → 2.0.0-alpha.16

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.
Files changed (62) hide show
  1. package/dist/base.d.ts +1 -1
  2. package/dist/base.d.ts.map +1 -1
  3. package/dist/base.js +11 -4
  4. package/dist/builder/directory.d.ts +1 -1
  5. package/dist/builder/directory.d.ts.map +1 -1
  6. package/dist/builder/directory.js +4 -2
  7. package/dist/builder/docker.d.ts +1 -1
  8. package/dist/builder/docker.d.ts.map +1 -1
  9. package/dist/builder/docker.js +31 -29
  10. package/dist/builder/empty.d.ts +1 -1
  11. package/dist/builder/empty.d.ts.map +1 -1
  12. package/dist/builder/none.d.ts +1 -1
  13. package/dist/builder/none.d.ts.map +1 -1
  14. package/dist/builder/tar.d.ts +1 -1
  15. package/dist/builder/tar.d.ts.map +1 -1
  16. package/dist/commands/build.d.ts +3 -1
  17. package/dist/commands/build.d.ts.map +1 -1
  18. package/dist/commands/build.js +73 -37
  19. package/dist/commands/deposit/erc20.d.ts +1 -2
  20. package/dist/commands/deposit/erc20.d.ts.map +1 -1
  21. package/dist/commands/deposit/erc20.js +2 -3
  22. package/dist/commands/deposit/erc721.d.ts +1 -3
  23. package/dist/commands/deposit/erc721.d.ts.map +1 -1
  24. package/dist/commands/deposit/erc721.js +0 -1
  25. package/dist/commands/deposit/ether.d.ts +1 -1
  26. package/dist/commands/deposit/ether.d.ts.map +1 -1
  27. package/dist/commands/deposit/ether.js +0 -1
  28. package/dist/commands/deposit.js +1 -1
  29. package/dist/commands/logs.d.ts.map +1 -1
  30. package/dist/commands/logs.js +3 -1
  31. package/dist/commands/run.js +1 -1
  32. package/dist/commands/send.js +2 -2
  33. package/dist/commands/shell.d.ts +2 -2
  34. package/dist/commands/shell.d.ts.map +1 -1
  35. package/dist/commands/shell.js +24 -19
  36. package/dist/compose/docker-compose-explorer.yaml +4 -1
  37. package/dist/config.d.ts +25 -5
  38. package/dist/config.d.ts.map +1 -1
  39. package/dist/config.js +70 -21
  40. package/dist/exec/cartesi-machine.d.ts.map +1 -1
  41. package/dist/exec/cartesi-machine.js +3 -5
  42. package/dist/exec/genext2fs.d.ts +4 -1
  43. package/dist/exec/genext2fs.d.ts.map +1 -1
  44. package/dist/exec/genext2fs.js +5 -5
  45. package/dist/exec/index.d.ts +0 -1
  46. package/dist/exec/index.d.ts.map +1 -1
  47. package/dist/exec/index.js +0 -1
  48. package/dist/exec/rollups.js +1 -1
  49. package/dist/exec/util.d.ts +0 -15
  50. package/dist/exec/util.d.ts.map +1 -1
  51. package/dist/exec/util.js +0 -45
  52. package/dist/machine.d.ts +7 -1
  53. package/dist/machine.d.ts.map +1 -1
  54. package/dist/machine.js +22 -15
  55. package/dist/prompts.d.ts.map +1 -1
  56. package/dist/prompts.js +2 -3
  57. package/dist/wallet.d.ts.map +1 -1
  58. package/dist/wallet.js +1 -1
  59. package/package.json +3 -3
  60. package/dist/exec/crane.d.ts +0 -15
  61. package/dist/exec/crane.d.ts.map +0 -1
  62. package/dist/exec/crane.js +0 -17
package/dist/base.d.ts CHANGED
@@ -2,7 +2,7 @@ import { type Address, type Hash } from "viem";
2
2
  import { type Config } from "./config.js";
3
3
  export declare const getContextPath: (...paths: string[]) => string;
4
4
  export declare const getMachineHash: () => Hash | undefined;
5
- export declare const getApplicationConfig: (configPath: string) => Config;
5
+ export declare const getApplicationConfig: (configPaths: string[]) => Config;
6
6
  export declare const getProjectName: (options: {
7
7
  projectName?: string;
8
8
  }) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,OAAO,EACZ,KAAK,IAAI,EAKZ,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,KAAK,MAAM,EAAS,MAAM,aAAa,CAAC;AAkBjD,eAAO,MAAM,cAAc,GAAI,GAAG,OAAO,MAAM,EAAE,KAAG,MAEnD,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,IAAI,GAAG,SAUxC,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,YAAY,MAAM,KAAG,MAIzD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,SAAS;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,WAE/D,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAElD,eAAO,MAAM,cAAc,GAAU,SAAS;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,KAAG,OAAO,CAAC,WAAW,CAkCtB,CAAC;AAqBF,eAAO,MAAM,eAAe,GAAU,SAAS;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACnB,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAG7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAU,SAAS;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACnB,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAG7B,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,KAAG,OAAO,GAAG,SAQtD,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,OAAO,MAAM,KAAG,IAQzC,CAAC"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,OAAO,EACZ,KAAK,IAAI,EAKZ,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,KAAK,MAAM,EAAS,MAAM,aAAa,CAAC;AAkBjD,eAAO,MAAM,cAAc,GAAI,GAAG,OAAO,MAAM,EAAE,KAAG,MAEnD,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,IAAI,GAAG,SAUxC,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,aAAa,MAAM,EAAE,KAAG,MAW5D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,SAAS;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,WAE/D,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAElD,eAAO,MAAM,cAAc,GAAU,SAAS;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,KAAG,OAAO,CAAC,WAAW,CAkCtB,CAAC;AAqBF,eAAO,MAAM,eAAe,GAAU,SAAS;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACnB,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAG7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAU,SAAS;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACnB,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAG7B,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,KAAG,OAAO,GAAG,SAQtD,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,OAAO,MAAM,KAAG,IAQzC,CAAC"}
package/dist/base.js CHANGED
@@ -20,10 +20,17 @@ export const getMachineHash = () => {
20
20
  }
21
21
  return undefined;
22
22
  };
23
- export const getApplicationConfig = (configPath) => {
24
- return fs.existsSync(configPath)
25
- ? parse(fs.readFileSync(configPath).toString())
26
- : parse("");
23
+ export const getApplicationConfig = (configPaths) => {
24
+ const tomls = configPaths.map((configPath) => {
25
+ if (fs.existsSync(configPath)) {
26
+ return fs.readFileSync(configPath).toString();
27
+ }
28
+ if (configPath === "cartesi.toml") {
29
+ return "";
30
+ }
31
+ throw new Error(`Config file ${configPath} does not exist`);
32
+ });
33
+ return parse(tomls);
27
34
  };
28
35
  export const getProjectName = (options) => {
29
36
  return options.projectName ?? path.basename(process.cwd());
@@ -1,3 +1,3 @@
1
1
  import type { DirectoryDriveConfig } from "../config.js";
2
- export declare const build: (name: string, drive: DirectoryDriveConfig, sdkImage: string, destination: string) => Promise<undefined>;
2
+ export declare const build: (name: string, drive: DirectoryDriveConfig, sdkImage: string, destination: string, debug: boolean) => Promise<void>;
3
3
  //# sourceMappingURL=directory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../../src/builder/directory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGzD,eAAO,MAAM,KAAK,GACd,MAAM,MAAM,EACZ,OAAO,oBAAoB,EAC3B,UAAU,MAAM,EAChB,aAAa,MAAM,KACpB,OAAO,CAAC,SAAS,CAkCnB,CAAC"}
1
+ {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../../src/builder/directory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGzD,eAAO,MAAM,KAAK,GACd,MAAM,MAAM,EACZ,OAAO,oBAAoB,EAC3B,UAAU,MAAM,EAChB,aAAa,MAAM,EACnB,OAAO,OAAO,KACf,OAAO,CAAC,IAAI,CAoCd,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import fs from "fs-extra";
2
2
  import path from "node:path";
3
3
  import { genext2fs, mksquashfs } from "../exec/index.js";
4
- export const build = async (name, drive, sdkImage, destination) => {
4
+ export const build = async (name, drive, sdkImage, destination, debug) => {
5
5
  const filename = `${name}.${drive.format}`;
6
6
  // copy directory to destination
7
7
  const dest = path.join(destination, name);
@@ -32,6 +32,8 @@ export const build = async (name, drive, sdkImage, destination) => {
32
32
  }
33
33
  finally {
34
34
  // delete copied
35
- await fs.remove(dest);
35
+ if (!debug) {
36
+ await fs.remove(dest);
37
+ }
36
38
  }
37
39
  };
@@ -5,6 +5,6 @@ type ImageInfo = {
5
5
  env: string[];
6
6
  workdir: string;
7
7
  };
8
- export declare const build: (name: string, drive: DockerDriveConfig, sdkImage: string, destination: string) => Promise<ImageInfo | undefined>;
8
+ export declare const build: (name: string, drive: DockerDriveConfig, sdkImage: string, destination: string, debug: boolean) => Promise<ImageInfo | undefined>;
9
9
  export {};
10
10
  //# sourceMappingURL=docker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/builder/docker.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAQtD,KAAK,SAAS,GAAG;IACb,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AA+DF,eAAO,MAAM,KAAK,GACd,MAAM,MAAM,EACZ,OAAO,iBAAiB,EACxB,UAAU,MAAM,EAChB,aAAa,MAAM,KACpB,OAAO,CAAC,SAAS,GAAG,SAAS,CA4D/B,CAAC"}
1
+ {"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/builder/docker.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAQtD,KAAK,SAAS,GAAG;IACb,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAiFF,eAAO,MAAM,KAAK,GACd,MAAM,MAAM,EACZ,OAAO,iBAAiB,EACxB,UAAU,MAAM,EAChB,aAAa,MAAM,EACnB,OAAO,OAAO,KACf,OAAO,CAAC,SAAS,GAAG,SAAS,CAsD/B,CAAC"}
@@ -1,33 +1,39 @@
1
1
  import { execa } from "execa";
2
2
  import fs from "fs-extra";
3
3
  import path from "node:path";
4
- import tmp from "tmp";
5
- import { crane, genext2fs, mksquashfs } from "../exec/index.js";
4
+ import { genext2fs, mksquashfs } from "../exec/index.js";
6
5
  /**
7
6
  * Build Docker image (linux/riscv64). Returns image id.
8
7
  */
9
8
  const buildImage = async (options) => {
10
- const { context, dockerfile, tags, target } = options;
11
- const buildResult = tmp.tmpNameSync();
9
+ const { buildArgs, context, destination, dockerfile, dockerfileContent, tags, target, } = options;
10
+ // if dockerfileContext is specified, use it as the dockerfile passed through stdin
12
11
  const args = [
13
12
  "buildx",
14
13
  "build",
15
14
  "--platform",
16
15
  "linux/riscv64",
17
16
  "--file",
18
- dockerfile,
19
- "--load",
20
- "--iidfile",
21
- buildResult,
22
- context,
17
+ dockerfileContent ? "-" : dockerfile,
18
+ "--output",
19
+ "type=docker",
20
+ "--output",
21
+ `type=tar,dest=${destination}`,
22
+ "--progress",
23
+ "quiet",
23
24
  ];
24
25
  // set tags for the image built
25
26
  args.push(...tags.flatMap((tag) => ["--tag", tag]));
27
+ // set build args
28
+ args.push(...buildArgs.flatMap((arg) => ["--build-arg", arg]));
26
29
  if (target) {
27
30
  args.push("--target", target);
28
31
  }
29
- await execa("docker", args, { stdio: "inherit" });
30
- return fs.readFileSync(buildResult, "utf8");
32
+ args.push(context);
33
+ const { stdout: imageId } = await execa("docker", args, {
34
+ input: dockerfileContent,
35
+ });
36
+ return imageId;
31
37
  };
32
38
  /**
33
39
  * Query the image using docker image inspect
@@ -54,33 +60,28 @@ const getImageInfo = async (image) => {
54
60
  };
55
61
  return info;
56
62
  };
57
- export const build = async (name, drive, sdkImage, destination) => {
63
+ export const build = async (name, drive, sdkImage, destination, debug) => {
58
64
  const { format } = drive;
59
- const ocitar = `${name}.oci.tar`;
60
65
  const tar = `${name}.tar`;
61
66
  const filename = `${name}.${format}`;
62
67
  // use pre-existing image or build docker image
63
68
  let image;
64
69
  if (drive.image) {
65
- image = drive.image;
66
- await execa("docker", ["image", "pull", image]);
70
+ // build a docker image with `FROM <image>`
71
+ image = await buildImage({
72
+ ...drive,
73
+ destination: path.join(destination, tar),
74
+ dockerfileContent: `FROM ${drive.image}`,
75
+ });
67
76
  }
68
77
  else {
69
- image = await buildImage(drive);
78
+ image = await buildImage({
79
+ ...drive,
80
+ destination: path.join(destination, tar),
81
+ });
70
82
  }
71
- // get image info
72
83
  const imageInfo = await getImageInfo(image);
73
84
  try {
74
- // create OCI Docker tarball from Docker image
75
- await execa("docker", ["image", "save", image, "-o", ocitar], {
76
- cwd: destination,
77
- });
78
- // create rootfs tar from OCI tar
79
- await crane.exportImage({
80
- stdin: fs.openSync(path.join(destination, ocitar), "r"),
81
- stdout: fs.openSync(path.join(destination, tar), "w"),
82
- image: sdkImage,
83
- });
84
85
  switch (format) {
85
86
  case "ext2": {
86
87
  await genext2fs.fromTar({
@@ -105,8 +106,9 @@ export const build = async (name, drive, sdkImage, destination) => {
105
106
  }
106
107
  finally {
107
108
  // delete intermediate files
108
- await fs.remove(path.join(destination, ocitar));
109
- await fs.remove(path.join(destination, tar));
109
+ if (!debug) {
110
+ await fs.remove(path.join(destination, tar));
111
+ }
110
112
  }
111
113
  return imageInfo;
112
114
  };
@@ -1,3 +1,3 @@
1
1
  import type { EmptyDriveConfig } from "../config.js";
2
- export declare const build: (name: string, drive: EmptyDriveConfig, sdkImage: string, destination: string) => Promise<undefined>;
2
+ export declare const build: (name: string, drive: EmptyDriveConfig, sdkImage: string, destination: string) => Promise<void>;
3
3
  //# sourceMappingURL=empty.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"empty.d.ts","sourceRoot":"","sources":["../../src/builder/empty.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD,eAAO,MAAM,KAAK,GACd,MAAM,MAAM,EACZ,OAAO,gBAAgB,EACvB,UAAU,MAAM,EAChB,aAAa,MAAM,KACpB,OAAO,CAAC,SAAS,CAoBnB,CAAC"}
1
+ {"version":3,"file":"empty.d.ts","sourceRoot":"","sources":["../../src/builder/empty.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD,eAAO,MAAM,KAAK,GACd,MAAM,MAAM,EACZ,OAAO,gBAAgB,EACvB,UAAU,MAAM,EAChB,aAAa,MAAM,KACpB,OAAO,CAAC,IAAI,CAoBd,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import { type ExistingDriveConfig } from "../config.js";
2
- export declare const build: (name: string, drive: ExistingDriveConfig, destination: string) => Promise<undefined>;
2
+ export declare const build: (name: string, drive: ExistingDriveConfig, destination: string) => Promise<void>;
3
3
  //# sourceMappingURL=none.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"none.d.ts","sourceRoot":"","sources":["../../src/builder/none.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,mBAAmB,EAAkB,MAAM,cAAc,CAAC;AAExE,eAAO,MAAM,KAAK,GACd,MAAM,MAAM,EACZ,OAAO,mBAAmB,EAC1B,aAAa,MAAM,KACpB,OAAO,CAAC,SAAS,CAQnB,CAAC"}
1
+ {"version":3,"file":"none.d.ts","sourceRoot":"","sources":["../../src/builder/none.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,mBAAmB,EAAkB,MAAM,cAAc,CAAC;AAExE,eAAO,MAAM,KAAK,GACd,MAAM,MAAM,EACZ,OAAO,mBAAmB,EAC1B,aAAa,MAAM,KACpB,OAAO,CAAC,IAAI,CAQd,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import type { TarDriveConfig } from "../config.js";
2
- export declare const build: (name: string, drive: TarDriveConfig, sdkImage: string, destination: string) => Promise<undefined>;
2
+ export declare const build: (name: string, drive: TarDriveConfig, sdkImage: string, destination: string) => Promise<void>;
3
3
  //# sourceMappingURL=tar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tar.d.ts","sourceRoot":"","sources":["../../src/builder/tar.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGnD,eAAO,MAAM,KAAK,GACd,MAAM,MAAM,EACZ,OAAO,cAAc,EACrB,UAAU,MAAM,EAChB,aAAa,MAAM,KACpB,OAAO,CAAC,SAAS,CA4BnB,CAAC"}
1
+ {"version":3,"file":"tar.d.ts","sourceRoot":"","sources":["../../src/builder/tar.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGnD,eAAO,MAAM,KAAK,GACd,MAAM,MAAM,EACZ,OAAO,cAAc,EACrB,UAAU,MAAM,EAChB,aAAa,MAAM,KACpB,OAAO,CAAC,IAAI,CA4Bd,CAAC"}
@@ -1,6 +1,8 @@
1
1
  import { Command } from "@commander-js/extra-typings";
2
2
  export declare const createBuildCommand: () => Command<[], {
3
- config: string;
3
+ config: string[];
4
+ debug: boolean;
4
5
  drivesOnly?: true | undefined;
6
+ verbose: boolean;
5
7
  }, {}>;
6
8
  //# sourceMappingURL=build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAwCtD,eAAO,MAAM,kBAAkB;;;MAoD9B,CAAC"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,6BAA6B,CAAC;AAqE9D,eAAO,MAAM,kBAAkB;;;;;MAqF9B,CAAC"}
@@ -1,61 +1,97 @@
1
- import { Command } from "@commander-js/extra-typings";
1
+ import { Command, Option } from "@commander-js/extra-typings";
2
+ import chalk from "chalk";
2
3
  import fs from "fs-extra";
4
+ import { Listr } from "listr2";
3
5
  import path from "node:path";
4
6
  import tmp from "tmp";
5
7
  import { getApplicationConfig, getContextPath } from "../base.js";
6
8
  import { buildDirectory, buildDocker, buildEmpty, buildNone, buildTar, } from "../builder/index.js";
7
9
  import { bootMachine } from "../machine.js";
8
- const buildDrive = async (name, drive, sdkImage, destination) => {
9
- switch (drive.builder) {
10
- case "directory": {
11
- return buildDirectory(name, drive, sdkImage, destination);
10
+ const buildDriveTask = (name, drive) => ({
11
+ title: `Building drive ${chalk.cyan(name)}`,
12
+ task: async (ctx, task) => {
13
+ const { config, debug, destination } = ctx;
14
+ const sdk = config.sdk;
15
+ switch (drive.builder) {
16
+ case "directory": {
17
+ await buildDirectory(name, drive, sdk, destination, debug);
18
+ break;
19
+ }
20
+ case "docker": {
21
+ const imageInfo = await buildDocker(name, drive, sdk, destination, debug);
22
+ if (imageInfo && name === "root") {
23
+ // only set image info for root drive
24
+ ctx.imageInfo = imageInfo;
25
+ }
26
+ break;
27
+ }
28
+ case "empty": {
29
+ await buildEmpty(name, drive, sdk, destination);
30
+ break;
31
+ }
32
+ case "tar": {
33
+ await buildTar(name, drive, sdk, destination);
34
+ break;
35
+ }
36
+ case "none": {
37
+ await buildNone(name, drive, destination);
38
+ break;
39
+ }
12
40
  }
13
- case "docker": {
14
- return buildDocker(name, drive, sdkImage, destination);
15
- }
16
- case "empty": {
17
- return buildEmpty(name, drive, sdkImage, destination);
18
- }
19
- case "tar": {
20
- return buildTar(name, drive, sdkImage, destination);
21
- }
22
- case "none": {
23
- return buildNone(name, drive, destination);
24
- }
25
- }
26
- };
41
+ task.title = `Build drive ${chalk.cyan(name)}`;
42
+ },
43
+ });
27
44
  export const createBuildCommand = () => {
28
45
  return new Command("build")
29
46
  .description("Build application by building Cartesi machine drives, configuring a machine and booting it.")
30
- .option("-c, --config <config>", "path to the configuration file", "cartesi.toml")
47
+ .option("-c, --config <config>", "path to the configuration file", (value, prev) => prev.concat([value]), ["cartesi.toml"])
48
+ .addOption(new Option("--debug", "enable debug mode (do not remove intermediate files)")
49
+ .default(false)
50
+ .hideHelp())
31
51
  .option("-d, --drives-only", "only build drives, do not boot machine")
32
- .action(async ({ config, drivesOnly }) => {
52
+ .option("-v, --verbose", "verbose output", false)
53
+ .action(async (options) => {
54
+ const { debug, drivesOnly, verbose } = options;
33
55
  // clean up temp files we create along the process
34
56
  tmp.setGracefulCleanup();
35
57
  // get application configuration from 'cartesi.toml'
36
- const c = getApplicationConfig(config);
58
+ const config = getApplicationConfig(options.config);
37
59
  // destination directory for image and intermediate files
38
60
  const destination = path.resolve(getContextPath());
39
61
  // prepare context directory
40
62
  await fs.emptyDir(destination); // XXX: make it less error prone
41
- // start build of all drives simultaneously
42
- const results = Object.entries(c.drives).reduce((acc, [name, drive]) => {
43
- acc[name] = buildDrive(name, drive, c.sdk, destination);
44
- return acc;
45
- }, {});
46
- // await for all drives to be built
47
- await Promise.all(Object.values(results));
63
+ // build context
64
+ const ctx = { config, debug, destination, imageInfo: undefined };
65
+ // tasks to build drives
66
+ const driveTasks = Object.entries(config.drives).map(([name, drive]) => buildDriveTask(name, drive));
67
+ const builds = new Listr([
68
+ {
69
+ title: "Build drives",
70
+ task: async (_ctx, task) => {
71
+ return task.newListr(driveTasks, {
72
+ concurrent: true,
73
+ rendererOptions: {
74
+ collapseSubtasks: false,
75
+ },
76
+ ctx,
77
+ });
78
+ },
79
+ },
80
+ ], { ctx, renderer: verbose ? "verbose" : "default" });
81
+ const result = await builds.run();
82
+ // if only build drives, quit here
48
83
  if (drivesOnly) {
49
- // only build drives, so quit here
50
84
  return;
51
85
  }
52
- // get image info of root drive
53
- const root = await results.root;
54
- const imageInfo = root || undefined;
55
- // path of machine snapshot
56
- const snapshotPath = getContextPath("image");
57
86
  // create machine snapshot
58
- await bootMachine(c, imageInfo, destination);
59
- await fs.chmod(snapshotPath, 0o755);
87
+ await bootMachine(config, result.imageInfo, {
88
+ finalHash: true,
89
+ store: "image",
90
+ }, {
91
+ cwd: destination,
92
+ stdio: "inherit",
93
+ });
94
+ // make snapshot readable by all users, because cartesi-machine sets to 600
95
+ await fs.chmod(path.join(destination, "image"), 0o755);
60
96
  });
61
97
  };
@@ -1,7 +1,6 @@
1
1
  import { Command } from "@commander-js/extra-typings";
2
2
  export declare const createErc20Command: () => Command<[string | undefined], {
3
- token?: string | undefined;
4
- execLayerData: string;
3
+ [x: string]: never;
5
4
  }, {
6
5
  from?: string | undefined;
7
6
  application?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"erc20.d.ts","sourceRoot":"","sources":["../../../src/commands/deposit/erc20.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AA4EtD,eAAO,MAAM,kBAAkB;;;;;;;;EAyG9B,CAAC"}
1
+ {"version":3,"file":"erc20.d.ts","sourceRoot":"","sources":["../../../src/commands/deposit/erc20.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AA4EtD,eAAO,MAAM,kBAAkB;;;;;;;EAwG9B,CAAC"}
@@ -38,7 +38,6 @@ const parseToken = async (options) => {
38
38
  return readToken(testClient, address);
39
39
  };
40
40
  export const createErc20Command = () => {
41
- // biome-ignore lint/complexity/noBannedTypes: commander pattern
42
41
  return new Command("erc20")
43
42
  .description("Deposit ERC-20 to the application")
44
43
  .configureHelp({ showGlobalOptions: true })
@@ -97,7 +96,7 @@ export const createErc20Command = () => {
97
96
  const amountLabel = `${chalk.cyan(formatUnits(amount, decimals))} ${symbol}`;
98
97
  // approve if needed
99
98
  if (allowance < amount) {
100
- progress.start(`Approving ${amountStr}...`);
99
+ progress.start(`Approving ${amountLabel}...`);
101
100
  const { request } = await testClient.simulateContract({
102
101
  abi: erc20Abi,
103
102
  account,
@@ -107,7 +106,7 @@ export const createErc20Command = () => {
107
106
  });
108
107
  const hash = await testClient.writeContract(request);
109
108
  await testClient.waitForTransactionReceipt({ hash });
110
- progress.succeed(`Approved ${amountStr}`);
109
+ progress.succeed(`Approved ${amountLabel}`);
111
110
  }
112
111
  // simulate deposit call
113
112
  const { request } = await testClient.simulateContract({
@@ -1,8 +1,6 @@
1
1
  import { Command } from "@commander-js/extra-typings";
2
2
  export declare const createErc721Command: () => Command<[string | undefined], {
3
- token?: string | undefined;
4
- baseLayerData: string;
5
- execLayerData: string;
3
+ [x: string]: never;
6
4
  }, {
7
5
  from?: string | undefined;
8
6
  application?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"erc721.d.ts","sourceRoot":"","sources":["../../../src/commands/deposit/erc721.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAuEtD,eAAO,MAAM,mBAAmB;;;;;;;;;EAoI/B,CAAC"}
1
+ {"version":3,"file":"erc721.d.ts","sourceRoot":"","sources":["../../../src/commands/deposit/erc721.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAuEtD,eAAO,MAAM,mBAAmB;;;;;;;EAmI/B,CAAC"}
@@ -33,7 +33,6 @@ const parseToken = async (options) => {
33
33
  return readToken(testClient, address);
34
34
  };
35
35
  export const createErc721Command = () => {
36
- // biome-ignore lint/complexity/noBannedTypes: commander pattern
37
36
  return new Command("erc721")
38
37
  .description("Deposit ERC-721 to the application")
39
38
  .configureHelp({ showGlobalOptions: true })
@@ -1,6 +1,6 @@
1
1
  import { Command } from "@commander-js/extra-typings";
2
2
  export declare const createEtherCommand: () => Command<[string | undefined], {
3
- execLayerData: string;
3
+ [x: string]: never;
4
4
  }, {
5
5
  from?: string | undefined;
6
6
  application?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"ether.d.ts","sourceRoot":"","sources":["../../../src/commands/deposit/ether.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAUtD,eAAO,MAAM,kBAAkB;;;;;;;EAyE9B,CAAC"}
1
+ {"version":3,"file":"ether.d.ts","sourceRoot":"","sources":["../../../src/commands/deposit/ether.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAUtD,eAAO,MAAM,kBAAkB;;;;;;;EAwE9B,CAAC"}
@@ -7,7 +7,6 @@ import { etherPortalAbi, etherPortalAddress } from "../../contracts.js";
7
7
  import { bigintInput, getInputApplicationAddress } from "../../prompts.js";
8
8
  import { connect } from "../../wallet.js";
9
9
  export const createEtherCommand = () => {
10
- // biome-ignore lint/complexity/noBannedTypes: commander pattern
11
10
  return new Command("ether")
12
11
  .description("Deposit ether to the application")
13
12
  .configureHelp({ showGlobalOptions: true })
@@ -11,7 +11,7 @@ export const createDepositCommand = () => {
11
11
  .option("--application <address>", "application address")
12
12
  .option("--project-name <string>", "name of project (used by docker compose and cartesi-rollups-node)")
13
13
  .option("--rpc-url <url>", "RPC URL of the Cartesi Devnet")
14
- .action(async (options, command) => {
14
+ .action(async (_options, command) => {
15
15
  // get registered subcommands
16
16
  const commands = command.commands;
17
17
  // create choices for the selected prompt based on registered subcommands
@@ -1 +1 @@
1
- {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAItD,eAAO,MAAM,iBAAiB;;;;;;;MA4C7B,CAAC"}
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAItD,eAAO,MAAM,iBAAiB;;;;;;;MA6C7B,CAAC"}
@@ -11,7 +11,7 @@ export const createLogsCommand = () => {
11
11
  .option("-n, --tail <string>", "Number of lines to show from the end of the logs", "all")
12
12
  .option("--until <string>", "Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)")
13
13
  .configureHelp({ showGlobalOptions: true })
14
- .action(async (options, command) => {
14
+ .action(async (options) => {
15
15
  const { follow, color, since, tail, until } = options;
16
16
  const projectName = getProjectName(options);
17
17
  const logOptions = ["--no-log-prefix"];
@@ -23,6 +23,8 @@ export const createLogsCommand = () => {
23
23
  logOptions.push("--since", since);
24
24
  if (tail)
25
25
  logOptions.push("--tail", tail);
26
+ if (until)
27
+ logOptions.push("--until", until);
26
28
  await execa("docker", [
27
29
  "compose",
28
30
  "--project-name",
@@ -13,7 +13,7 @@ const commaSeparatedList = (value) => value.split(",");
13
13
  const shell = async (options) => {
14
14
  const { build, epochLength, log, projectName } = options;
15
15
  // keep track of last deployment
16
- let lastDeployment = undefined;
16
+ let lastDeployment;
17
17
  let salt = 0;
18
18
  // deploy for the first time
19
19
  const hash = getMachineHash();
@@ -50,7 +50,7 @@ const getInput = async (input, options) => {
50
50
  try {
51
51
  return BigInt(v);
52
52
  }
53
- catch (e) {
53
+ catch {
54
54
  throw new Error(`Invalid uint value: ${v}`);
55
55
  }
56
56
  case "bytes":
@@ -95,7 +95,7 @@ export const createSendCommand = () => {
95
95
  .option("--abi-params <abi-params>", "input abi params")
96
96
  .option("--project-name <string>", "name of project (used by docker compose and cartesi-rollups-node)")
97
97
  .option("--rpc-url <url>", "RPC URL of the Cartesi Devnet")
98
- .action(async (input, options, program) => {
98
+ .action(async (input, options) => {
99
99
  const { application, from } = options;
100
100
  const projectName = getProjectName(options);
101
101
  // connect to anvil
@@ -1,7 +1,7 @@
1
1
  import { Command } from "@commander-js/extra-typings";
2
- export declare const createShellCommand: () => Command<[string | undefined], {
2
+ export declare const createShellCommand: () => Command<[], {
3
3
  command: string;
4
- config: string;
4
+ config: string[];
5
5
  runAsRoot: boolean;
6
6
  }, {}>;
7
7
  //# sourceMappingURL=shell.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/commands/shell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAOtD,eAAO,MAAM,kBAAkB;;;;MAiD9B,CAAC"}
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/commands/shell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAOtD,eAAO,MAAM,kBAAkB;;;;MAuD9B,CAAC"}
@@ -1,21 +1,22 @@
1
1
  import { Command } from "@commander-js/extra-typings";
2
+ import { ExecaError } from "execa";
2
3
  import fs from "fs-extra";
3
4
  import path from "node:path";
4
5
  import { getApplicationConfig, getContextPath } from "../base.js";
5
6
  import { bootMachine } from "../machine.js";
6
7
  export const createShellCommand = () => {
7
8
  return new Command("shell")
8
- .argument("[image]", "image ID|name")
9
9
  .option("--command <command>", "shell command to run", "/bin/sh")
10
- .option("-c, --config <config>", "path to the configuration file", "cartesi.toml")
10
+ .option("-c, --config <config>", "path to the configuration file", (value, prev) => prev.concat([value]), ["cartesi.toml"])
11
11
  .option("--run-as-root", "run as root user", false)
12
- .action(async (image, { command, config, runAsRoot }) => {
12
+ .action(async (options) => {
13
+ const { command, runAsRoot } = options;
13
14
  // get application configuration from 'cartesi.toml'
14
- const c = getApplicationConfig(config);
15
+ const config = getApplicationConfig(options.config);
15
16
  // destination directory for image and intermediate files
16
17
  const destination = path.resolve(getContextPath());
17
18
  // check if all drives are built
18
- for (const [name, drive] of Object.entries(c.drives)) {
19
+ for (const [name, drive] of Object.entries(config.drives)) {
19
20
  const filename = `${name}.${drive.format}`;
20
21
  const pathname = getContextPath(filename);
21
22
  if (!fs.existsSync(pathname)) {
@@ -23,21 +24,25 @@ export const createShellCommand = () => {
23
24
  }
24
25
  }
25
26
  // create shell entrypoint
26
- const info = {
27
- cmd: [],
28
- entrypoint: [command],
29
- env: [],
30
- workdir: "/",
31
- };
32
- // start with interactive mode on
33
- c.machine.interactive = true;
34
- // interactive mode can't have final hash
35
- c.machine.finalHash = false;
36
- // do not store machine in interactive mode
37
- c.machine.store = undefined;
27
+ config.machine.entrypoint = command;
38
28
  // run as root if flag is set
39
- c.machine.user = runAsRoot ? "root" : undefined;
29
+ config.machine.user = runAsRoot ? "root" : undefined;
40
30
  // boot machine
41
- await bootMachine(c, info, destination);
31
+ try {
32
+ await bootMachine(config, undefined, { interactive: true }, // start with interactive mode on
33
+ {
34
+ cwd: destination,
35
+ stdio: "inherit",
36
+ });
37
+ }
38
+ catch (error) {
39
+ if (error instanceof ExecaError) {
40
+ // just continue gracefully
41
+ if (error.exitCode === 130) {
42
+ return;
43
+ }
44
+ throw error;
45
+ }
46
+ }
42
47
  });
43
48
  };
@@ -78,7 +78,10 @@ services:
78
78
  condition: service_healthy
79
79
 
80
80
  explorer:
81
- image: cartesi/rollups-explorer:1.0.2
81
+ image: cartesi/rollups-explorer:1.2.0
82
+ environment:
83
+ NODE_RPC_URL: "http://127.0.0.1:${CARTESI_LISTEN_PORT:-6751}/anvil"
84
+ EXPLORER_API_URL: "http://127.0.0.1:${CARTESI_LISTEN_PORT:-6751}/explorer-api/graphql"
82
85
  expose:
83
86
  - 3000
84
87
  depends_on: