1use clap::{ArgAction, Args, Parser, Subcommand, ValueEnum};
2use std::path::PathBuf;
3
4use multiversx_sc_meta_lib::cli::{CliArgsToRaw, ContractCliAction};
5
6#[derive(Default, PartialEq, Eq, Debug, Parser)]
8#[command(
9 version,
10 about,
11 after_help = "
12The MultiversX smart contract Meta crate can be used in two ways:
13 A. Import it into a contract's specific meta-crate.
14 There it will receive access to the contract ABI generator.
15 Based on that it is able to build the contract and apply various tools.
16 This part also contains the multi-contract config infrastructure.
17
18 B. Use it as a standalone tool.
19 It can be used to automatically upgrade contracts from one version to the next.
20
21You are currently using the standalone tool (B).
22"
23)]
24#[command(propagate_version = true)]
25pub struct StandaloneCliArgs {
26 #[command(subcommand)]
27 pub command: Option<StandaloneCliAction>,
28}
29
30#[derive(Clone, PartialEq, Eq, Debug, Subcommand)]
31pub enum StandaloneCliAction {
32 #[command(name = "install", about = "Installs framework dependencies")]
33 Install(InstallArgs),
34
35 #[command(
36 about = "General info about the contract an libraries residing in the targeted directory.."
37 )]
38 Info(InfoArgs),
39
40 #[command(
41 about = "Calls the meta crates for all contracts under given path with the given arguments."
42 )]
43 All(AllArgs),
44
45 #[command(
46 about = "Upgrades a contract to the latest version. Multiple contract crates are allowed."
47 )]
48 Upgrade(UpgradeArgs),
49
50 #[command(name = "new", about = "Creates a contract by a pre-existing template")]
51 Template(TemplateArgs),
52
53 #[command(name = "templates", about = "Lists all pre-existing templates")]
54 TemplateList(TemplateListArgs),
55
56 #[command(
57 name = "test-gen",
58 about = "Generates Rust integration tests based on scenarios provided in the scenarios folder of each contract."
59 )]
60 TestGen(TestGenArgs),
61
62 #[command(name = "test", about = "Runs cargo test")]
63 Test(TestArgs),
64
65 #[command(name = "test-coverage", about = "Run test coverage and output report")]
66 TestCoverage(TestCoverageArgs),
67
68 #[command(name = "report", about = "Generate code report")]
69 CodeReportGen(CodeReportArgs),
70
71 #[command(
72 about = "Generates a scenario test initialized with real data fetched from the blockchain."
73 )]
74 Account(AccountArgs),
75
76 #[command(
77 name = "local-deps",
78 about = "Generates a report on the local dependencies of contract crates. Will explore indirect dependencies too."
79 )]
80 LocalDeps(LocalDepsArgs),
81
82 #[command(
83 name = "wallet",
84 about = "Generates a new wallet or performs actions on an existing wallet."
85 )]
86 Wallet(WalletArgs),
87
88 #[command(
89 name = "cs",
90 about = "Can install, start and stop a chain simulator configuration."
91 )]
92 ChainSimulator(ChainSimulatorArgs),
93}
94
95#[derive(Clone, PartialEq, Eq, Debug, Args)]
96pub struct ChainSimulatorArgs {
97 #[command(subcommand)]
98 pub command: ChainSimulatorCommand,
99}
100
101#[derive(Clone, PartialEq, Eq, Debug, Subcommand)]
102pub enum ChainSimulatorCommand {
103 #[command(
104 about = "Pulls the latest chain simulator docker image available. Needs Docker installed."
105 )]
106 Install,
107
108 #[command(about = "Starts the chain simulator.")]
109 Start,
110
111 #[command(about = "Stops the chain simulator.")]
112 Stop,
113}
114
115#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
116pub struct InfoArgs {
117 #[arg(long, verbatim_doc_comment)]
120 pub path: Option<String>,
121
122 #[arg(long, verbatim_doc_comment)]
124 #[clap(global = true, default_value = "target")]
125 pub ignore: Vec<String>,
126}
127
128#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
129pub struct TestArgs {
130 #[arg(short, long)]
132 pub path: Option<String>,
133
134 #[arg(short, long, default_value = "false")]
136 pub go: bool,
137
138 #[arg(short, long, default_value = "false")]
140 pub wasm: bool,
141
142 #[arg(
144 short = 'c',
145 long = "chain-simulator",
146 default_value = "false",
147 verbatim_doc_comment
148 )]
149 pub chain_simulator: bool,
150
151 #[arg(short, long, default_value = "false", verbatim_doc_comment)]
154 pub scen: bool,
155
156 #[arg(short, long, default_value = "false", verbatim_doc_comment)]
158 pub nocapture: bool,
159}
160
161#[derive(Default, Clone, PartialEq, Eq, Debug, ValueEnum)]
162pub enum OutputFormat {
163 #[default]
165 Markdown,
166
167 Json,
169}
170
171#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
172pub struct TestCoverageArgs {
173 #[arg(short, long, verbatim_doc_comment)]
175 pub output: String,
176
177 #[arg(short, long, verbatim_doc_comment)]
179 pub format: Option<OutputFormat>,
180
181 #[arg(short = 'i', long = "ignore-filename-regex", verbatim_doc_comment)]
183 pub ignore_filename_regex: Vec<String>,
184}
185
186#[derive(Clone, PartialEq, Eq, Debug, Args)]
187pub struct CodeReportArgs {
188 #[command(subcommand)]
189 pub command: CodeReportAction,
190}
191
192#[derive(Clone, PartialEq, Eq, Debug, Subcommand)]
193pub enum CodeReportAction {
194 #[command(name = "compile", about = "Generates the contract report.")]
195 Compile(CompileArgs),
196
197 #[command(name = "compare", about = "Compare two contract reports.")]
198 Compare(CompareArgs),
199
200 #[command(
201 name = "convert",
202 about = "Converts a contract report to a Markdown file."
203 )]
204 Convert(ConvertArgs),
205}
206
207#[derive(Clone, PartialEq, Eq, Debug, Args)]
208pub struct CompileArgs {
209 #[arg(short, long, verbatim_doc_comment)]
211 pub path: PathBuf,
212
213 #[arg(short, long, verbatim_doc_comment)]
215 pub output: PathBuf,
216}
217
218#[derive(Clone, PartialEq, Eq, Debug, Args)]
219pub struct CompareArgs {
220 #[arg(short, long, verbatim_doc_comment)]
223 pub baseline: PathBuf,
224
225 #[arg(short, long, verbatim_doc_comment)]
228 pub new: PathBuf,
229
230 #[arg(short, long, verbatim_doc_comment)]
232 pub output: PathBuf,
233}
234
235#[derive(Clone, PartialEq, Eq, Debug, Args)]
236pub struct ConvertArgs {
237 #[arg(short, long, verbatim_doc_comment)]
239 pub input: PathBuf,
240
241 #[arg(short, long, verbatim_doc_comment)]
243 pub output: PathBuf,
244}
245
246#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
247pub struct AllArgs {
248 #[command(subcommand)]
249 pub command: ContractCliAction,
250
251 #[arg(long, verbatim_doc_comment)]
254 #[clap(global = true)]
255 pub path: Option<String>,
256
257 #[arg(long, verbatim_doc_comment)]
259 #[clap(global = true, default_value = "target")]
260 pub ignore: Vec<String>,
261
262 #[arg(
263 long = "no-abi-git-version",
264 help = "Skips loading the Git version into the ABI",
265 action = ArgAction::SetFalse
266 )]
267 #[clap(global = true)]
268 pub load_abi_git_version: bool,
269
270 #[arg(long = "target-dir-meta", verbatim_doc_comment)]
273 #[clap(global = true)]
274 pub target_dir_meta: Option<String>,
275
276 #[arg(long = "target-dir-all", verbatim_doc_comment)]
278 #[clap(global = true)]
279 pub target_dir_all: Option<String>,
280}
281
282impl AllArgs {
283 pub fn target_dir_all_override(&self) -> Self {
284 let mut result = self.clone();
285 if let Some(target_dir_all) = &self.target_dir_all {
286 result.target_dir_meta = Some(target_dir_all.clone());
287 match &mut result.command {
288 ContractCliAction::Build(build_args) => {
289 build_args.target_dir_wasm = Some(target_dir_all.clone());
290 }
291 ContractCliAction::BuildDbg(build_args) => {
292 build_args.target_dir_wasm = Some(target_dir_all.clone());
293 }
294 ContractCliAction::Twiggy(build_args) => {
295 build_args.target_dir_wasm = Some(target_dir_all.clone());
296 }
297 _ => {}
298 }
299 }
300 result
301 }
302
303 pub fn to_cargo_run_args(&self) -> Vec<String> {
304 let processed = self.target_dir_all_override();
305 let mut raw = vec!["run".to_string()];
306 if let Some(target_dir_meta) = &processed.target_dir_meta {
307 raw.push("--target-dir".to_string());
308 raw.push(target_dir_meta.clone());
309 }
310 raw.append(&mut processed.command.to_raw());
311 if !processed.load_abi_git_version {
312 raw.push("--no-abi-git-version".to_string());
313 }
314 raw
315 }
316
317 pub fn to_cargo_abi_for_build(&self) -> Vec<String> {
321 let processed = self.target_dir_all_override();
322 let mut raw = vec!["run".to_string()];
323 if let Some(target_dir_meta) = &processed.target_dir_meta {
324 raw.push("--target-dir".to_string());
325 raw.push(target_dir_meta.clone());
326 }
327 raw.push("abi".to_string());
328 if !processed.load_abi_git_version {
329 raw.push("--no-abi-git-version".to_string());
330 }
331 raw
332 }
333}
334
335#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
336pub struct UpgradeArgs {
337 #[arg(long, verbatim_doc_comment)]
340 pub path: Option<String>,
341
342 #[arg(long, verbatim_doc_comment)]
344 #[clap(global = true, default_value = "target")]
345 pub ignore: Vec<String>,
346
347 #[arg(long = "to", verbatim_doc_comment)]
350 pub override_target_version: Option<String>,
351
352 #[arg(short, long, default_value = "false", verbatim_doc_comment)]
354 pub no_check: bool,
355}
356
357#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
358pub struct LocalDepsArgs {
359 #[arg(long, verbatim_doc_comment)]
362 pub path: Option<String>,
363
364 #[arg(long, verbatim_doc_comment)]
366 #[clap(global = true, default_value = "target")]
367 pub ignore: Vec<String>,
368}
369
370#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
371pub struct TemplateArgs {
372 #[arg(long, verbatim_doc_comment)]
375 pub name: Option<String>,
376
377 #[arg(long, verbatim_doc_comment)]
379 pub template: String,
380
381 #[arg(long, verbatim_doc_comment)]
383 pub tag: Option<String>,
384
385 #[arg(long, verbatim_doc_comment)]
388 pub path: Option<PathBuf>,
389
390 #[arg(long, verbatim_doc_comment)]
393 pub author: Option<String>,
394}
395
396impl CliArgsToRaw for TemplateArgs {
397 fn to_raw(&self) -> Vec<String> {
398 Vec::new()
399 }
400}
401
402#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
403pub struct TemplateListArgs {
404 #[arg(long = "tag", verbatim_doc_comment)]
406 pub tag: Option<String>,
407}
408
409#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
410pub struct TestGenArgs {
411 #[arg(long, verbatim_doc_comment)]
414 pub path: Option<String>,
415
416 #[arg(long, verbatim_doc_comment)]
418 #[clap(global = true, default_value = "target")]
419 pub ignore: Vec<String>,
420
421 #[arg(long, verbatim_doc_comment)]
423 pub create: bool,
424}
425
426#[derive(Default, PartialEq, Eq, Debug, Clone, Parser)]
427#[command(propagate_version = true)]
428pub struct InstallArgs {
429 #[command(subcommand)]
430 pub command: Option<InstallCommand>,
431}
432
433#[derive(Clone, PartialEq, Eq, Debug, Subcommand)]
434pub enum InstallCommand {
435 #[command(about = "Installs all the known tools")]
436 All,
437
438 #[command(about = "Installs the `mx-scenario-go` tool")]
439 MxScenarioGo(InstallMxScenarioGoArgs),
440
441 #[command(name = "wasm32", about = "Installs the `wasm32` target")]
442 Wasm32(InstallWasm32Args),
443
444 #[command(name = "wasm-opt", about = "Installs the `wasm-opt` tool")]
445 WasmOpt(InstallWasmOptArgs),
446
447 #[command(name = "debugger", about = "Installs the lldb debugger script tool")]
448 Debugger(InstallDebuggerArgs),
449}
450
451#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
452pub struct InstallMxScenarioGoArgs {
453 #[arg(long, verbatim_doc_comment)]
455 pub tag: Option<String>,
456}
457
458#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
459pub struct InstallWasm32Args {}
460
461#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
462pub struct InstallWasmOptArgs {}
463
464#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
465pub struct InstallDebuggerArgs {}
466
467#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
468pub struct AccountArgs {
469 #[arg(long = "api")]
471 #[clap(global = true)]
472 pub api: Option<String>,
473
474 #[arg(long = "address", verbatim_doc_comment)]
476 pub address: String,
477}
478
479#[derive(Clone, PartialEq, Eq, Debug, Subcommand)]
480pub enum WalletAction {
481 #[command(name = "new", about = "Creates a new wallet")]
482 New(WalletNewArgs),
483
484 #[command(
485 name = "bech32",
486 about = "Encodes/decodes a bech32 address to/from hex"
487 )]
488 Bech32(WalletBech32Args),
489 #[command(name = "convert", about = "Converts a wallet")]
490 Convert(WalletConvertArgs),
491}
492
493#[derive(Clone, PartialEq, Eq, Debug, Parser)]
494#[command(propagate_version = true)]
495pub struct WalletArgs {
496 #[command(subcommand)]
497 pub command: WalletAction,
498}
499
500#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
501pub struct WalletNewArgs {
502 #[arg(long = "format", verbatim_doc_comment)]
504 pub wallet_format: Option<String>,
505
506 #[arg(long = "outfile", verbatim_doc_comment)]
508 pub outfile: Option<String>,
509
510 #[arg(long = "hrp", verbatim_doc_comment)]
511 pub hrp: Option<String>,
512}
513
514#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
515pub struct WalletConvertArgs {
516 #[arg(long = "in-format", verbatim_doc_comment)]
517 pub from: String,
518
519 #[arg(long = "out-format", verbatim_doc_comment)]
520 pub to: String,
521
522 #[arg(long = "infile", verbatim_doc_comment)]
523 pub infile: Option<String>,
524
525 #[arg(long = "outfile", verbatim_doc_comment)]
526 pub outfile: Option<String>,
527
528 #[arg(long = "hrp", verbatim_doc_comment)]
529 pub hrp: Option<String>,
530}
531
532#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
533pub struct WalletBech32Args {
534 #[arg(long = "encode", verbatim_doc_comment)]
535 pub hex_address: Option<String>,
536 #[arg(long = "decode", verbatim_doc_comment)]
537 pub bech32_address: Option<String>,
538}