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(
63 name = "scen-blackbox",
64 about = "Generates blackbox tests from scenario files (.scen.json)."
65 )]
66 ScenBlackbox(ScenBlackboxArgs),
67
68 #[command(name = "test", about = "Runs cargo test")]
69 Test(TestArgs),
70
71 #[command(name = "test-coverage", about = "Run test coverage and output report")]
72 TestCoverage(TestCoverageArgs),
73
74 #[command(name = "report", about = "Generate code report")]
75 CodeReportGen(CodeReportArgs),
76
77 #[command(
78 about = "Generates a scenario test initialized with real data fetched from the blockchain."
79 )]
80 Account(AccountArgs),
81
82 #[command(
83 name = "local-deps",
84 about = "Generates a report on the local dependencies of contract crates. Will explore indirect dependencies too."
85 )]
86 LocalDeps(LocalDepsArgs),
87
88 #[command(
89 name = "wallet",
90 about = "Generates a new wallet or performs actions on an existing wallet."
91 )]
92 Wallet(WalletArgs),
93
94 #[command(
95 name = "cs",
96 about = "Can install, start and stop a chain simulator configuration."
97 )]
98 ChainSimulator(ChainSimulatorArgs),
99}
100
101#[derive(Clone, PartialEq, Eq, Debug, Args)]
102pub struct ChainSimulatorArgs {
103 #[command(subcommand)]
104 pub command: ChainSimulatorCommand,
105}
106
107#[derive(Clone, PartialEq, Eq, Debug, Subcommand)]
108pub enum ChainSimulatorCommand {
109 #[command(
110 about = "Pulls the latest chain simulator docker image available. Needs Docker installed."
111 )]
112 Install,
113
114 #[command(about = "Starts the chain simulator.")]
115 Start,
116
117 #[command(about = "Stops the chain simulator.")]
118 Stop,
119}
120
121#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
122pub struct InfoArgs {
123 #[arg(long, verbatim_doc_comment)]
126 pub path: Option<String>,
127
128 #[arg(long, verbatim_doc_comment)]
130 #[clap(global = true, default_value = "target")]
131 pub ignore: Vec<String>,
132}
133
134#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
135pub struct TestArgs {
136 #[arg(short, long)]
138 pub path: Option<String>,
139
140 #[arg(short, long, default_value = "false")]
142 pub go: bool,
143
144 #[arg(short, long, default_value = "false")]
146 pub wasm: bool,
147
148 #[arg(
150 short = 'c',
151 long = "chain-simulator",
152 default_value = "false",
153 verbatim_doc_comment
154 )]
155 pub chain_simulator: bool,
156
157 #[arg(short, long, default_value = "false", verbatim_doc_comment)]
160 pub scen: bool,
161
162 #[arg(short, long, default_value = "false", verbatim_doc_comment)]
164 pub nocapture: bool,
165}
166
167#[derive(Default, Clone, PartialEq, Eq, Debug, ValueEnum)]
168pub enum OutputFormat {
169 #[default]
171 Markdown,
172
173 Json,
175}
176
177#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
178pub struct TestCoverageArgs {
179 #[arg(short, long, verbatim_doc_comment)]
181 pub output: String,
182
183 #[arg(short, long, verbatim_doc_comment)]
185 pub format: Option<OutputFormat>,
186
187 #[arg(short = 'i', long = "ignore-filename-regex", verbatim_doc_comment)]
189 pub ignore_filename_regex: Vec<String>,
190}
191
192#[derive(Clone, PartialEq, Eq, Debug, Args)]
193pub struct CodeReportArgs {
194 #[command(subcommand)]
195 pub command: CodeReportAction,
196}
197
198#[derive(Clone, PartialEq, Eq, Debug, Subcommand)]
199pub enum CodeReportAction {
200 #[command(name = "compile", about = "Generates the contract report.")]
201 Compile(CompileArgs),
202
203 #[command(name = "compare", about = "Compare two contract reports.")]
204 Compare(CompareArgs),
205
206 #[command(
207 name = "convert",
208 about = "Converts a contract report to a Markdown file."
209 )]
210 Convert(ConvertArgs),
211}
212
213#[derive(Clone, PartialEq, Eq, Debug, Args)]
214pub struct CompileArgs {
215 #[arg(short, long, verbatim_doc_comment)]
217 pub path: PathBuf,
218
219 #[arg(short, long, verbatim_doc_comment)]
221 pub output: PathBuf,
222}
223
224#[derive(Clone, PartialEq, Eq, Debug, Args)]
225pub struct CompareArgs {
226 #[arg(short, long, verbatim_doc_comment)]
229 pub baseline: PathBuf,
230
231 #[arg(short, long, verbatim_doc_comment)]
234 pub new: PathBuf,
235
236 #[arg(short, long, verbatim_doc_comment)]
238 pub output: PathBuf,
239}
240
241#[derive(Clone, PartialEq, Eq, Debug, Args)]
242pub struct ConvertArgs {
243 #[arg(short, long, verbatim_doc_comment)]
245 pub input: PathBuf,
246
247 #[arg(short, long, verbatim_doc_comment)]
249 pub output: PathBuf,
250}
251
252#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
253pub struct AllArgs {
254 #[command(subcommand)]
255 pub command: ContractCliAction,
256
257 #[arg(long, verbatim_doc_comment)]
260 #[clap(global = true)]
261 pub path: Option<String>,
262
263 #[arg(long, verbatim_doc_comment)]
265 #[clap(global = true, default_value = "target")]
266 pub ignore: Vec<String>,
267
268 #[arg(
269 long = "no-abi-git-version",
270 help = "Skips loading the Git version into the ABI",
271 action = ArgAction::SetFalse
272 )]
273 #[clap(global = true)]
274 pub load_abi_git_version: bool,
275
276 #[arg(long = "target-dir-meta", verbatim_doc_comment)]
279 #[clap(global = true)]
280 pub target_dir_meta: Option<String>,
281
282 #[arg(long = "target-dir-all", verbatim_doc_comment)]
284 #[clap(global = true)]
285 pub target_dir_all: Option<String>,
286}
287
288impl AllArgs {
289 pub fn target_dir_all_override(&self) -> Self {
290 let mut result = self.clone();
291 if let Some(target_dir_all) = &self.target_dir_all {
292 result.target_dir_meta = Some(target_dir_all.clone());
293 match &mut result.command {
294 ContractCliAction::Build(build_args) => {
295 build_args.target_dir_wasm = Some(target_dir_all.clone());
296 }
297 ContractCliAction::BuildDbg(build_args) => {
298 build_args.target_dir_wasm = Some(target_dir_all.clone());
299 }
300 ContractCliAction::Twiggy(build_args) => {
301 build_args.target_dir_wasm = Some(target_dir_all.clone());
302 }
303 _ => {}
304 }
305 }
306 result
307 }
308
309 pub fn to_cargo_run_args(&self) -> Vec<String> {
310 let processed = self.target_dir_all_override();
311 let mut raw = vec!["run".to_string()];
312 if let Some(target_dir_meta) = &processed.target_dir_meta {
313 raw.push("--target-dir".to_string());
314 raw.push(target_dir_meta.clone());
315 }
316 raw.append(&mut processed.command.to_raw());
317 if !processed.load_abi_git_version {
318 raw.push("--no-abi-git-version".to_string());
319 }
320 raw
321 }
322
323 pub fn to_cargo_abi_for_build(&self) -> Vec<String> {
327 let processed = self.target_dir_all_override();
328 let mut raw = vec!["run".to_string()];
329 if let Some(target_dir_meta) = &processed.target_dir_meta {
330 raw.push("--target-dir".to_string());
331 raw.push(target_dir_meta.clone());
332 }
333 raw.push("abi".to_string());
334 if !processed.load_abi_git_version {
335 raw.push("--no-abi-git-version".to_string());
336 }
337 raw
338 }
339}
340
341#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
342pub struct UpgradeArgs {
343 #[arg(long, verbatim_doc_comment)]
346 pub path: Option<String>,
347
348 #[arg(long, verbatim_doc_comment)]
350 #[clap(global = true, default_value = "target")]
351 pub ignore: Vec<String>,
352
353 #[arg(long = "to", verbatim_doc_comment)]
356 pub override_target_version: Option<String>,
357
358 #[arg(short, long, default_value = "false", verbatim_doc_comment)]
360 pub no_check: bool,
361}
362
363#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
364pub struct LocalDepsArgs {
365 #[arg(long, verbatim_doc_comment)]
368 pub path: Option<String>,
369
370 #[arg(long, verbatim_doc_comment)]
372 #[clap(global = true, default_value = "target")]
373 pub ignore: Vec<String>,
374}
375
376#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
377pub struct TemplateArgs {
378 #[arg(long, verbatim_doc_comment)]
381 pub name: Option<String>,
382
383 #[arg(long, verbatim_doc_comment)]
385 pub template: String,
386
387 #[arg(long, verbatim_doc_comment)]
389 pub tag: Option<String>,
390
391 #[arg(long, verbatim_doc_comment)]
394 pub path: Option<PathBuf>,
395
396 #[arg(long, verbatim_doc_comment)]
399 pub author: Option<String>,
400}
401
402impl CliArgsToRaw for TemplateArgs {
403 fn to_raw(&self) -> Vec<String> {
404 Vec::new()
405 }
406}
407
408#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
409pub struct TemplateListArgs {
410 #[arg(long = "tag", verbatim_doc_comment)]
412 pub tag: Option<String>,
413}
414
415#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
416pub struct TestGenArgs {
417 #[arg(long, verbatim_doc_comment)]
420 pub path: Option<String>,
421
422 #[arg(long, verbatim_doc_comment)]
424 #[clap(global = true, default_value = "target")]
425 pub ignore: Vec<String>,
426
427 #[arg(long, verbatim_doc_comment)]
429 pub create: bool,
430}
431
432#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
433pub struct ScenBlackboxArgs {
434 #[arg(long, verbatim_doc_comment)]
437 pub path: Option<String>,
438
439 #[arg(long, verbatim_doc_comment)]
441 pub overwrite: bool,
442
443 #[arg(long, verbatim_doc_comment)]
445 #[clap(global = true, default_value = "target")]
446 pub ignore: Vec<String>,
447
448 #[arg(long, verbatim_doc_comment)]
451 pub output: Option<String>,
452}
453
454#[derive(Default, PartialEq, Eq, Debug, Clone, Parser)]
455#[command(propagate_version = true)]
456pub struct InstallArgs {
457 #[command(subcommand)]
458 pub command: Option<InstallCommand>,
459}
460
461#[derive(Clone, PartialEq, Eq, Debug, Subcommand)]
462pub enum InstallCommand {
463 #[command(about = "Installs all the known tools")]
464 All,
465
466 #[command(about = "Installs the `mx-scenario-go` tool")]
467 MxScenarioGo(InstallMxScenarioGoArgs),
468
469 #[command(name = "wasm32", about = "Installs the `wasm32` target")]
470 Wasm32(InstallWasm32Args),
471
472 #[command(name = "wasm-opt", about = "Installs the `wasm-opt` tool")]
473 WasmOpt(InstallWasmOptArgs),
474
475 #[command(name = "debugger", about = "Installs the lldb debugger script tool")]
476 Debugger(InstallDebuggerArgs),
477}
478
479#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
480pub struct InstallMxScenarioGoArgs {
481 #[arg(long, verbatim_doc_comment)]
483 pub tag: Option<String>,
484}
485
486#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
487pub struct InstallWasm32Args {}
488
489#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
490pub struct InstallWasmOptArgs {}
491
492#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
493pub struct InstallDebuggerArgs {}
494
495#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
496pub struct AccountArgs {
497 #[arg(long = "api")]
499 #[clap(global = true)]
500 pub api: Option<String>,
501
502 #[arg(long = "address", verbatim_doc_comment)]
504 pub address: String,
505}
506
507#[derive(Clone, PartialEq, Eq, Debug, Subcommand)]
508pub enum WalletAction {
509 #[command(name = "new", about = "Creates a new wallet")]
510 New(WalletNewArgs),
511
512 #[command(
513 name = "bech32",
514 about = "Encodes/decodes a bech32 address to/from hex"
515 )]
516 Bech32(WalletBech32Args),
517 #[command(name = "convert", about = "Converts a wallet")]
518 Convert(WalletConvertArgs),
519}
520
521#[derive(Clone, PartialEq, Eq, Debug, Parser)]
522#[command(propagate_version = true)]
523pub struct WalletArgs {
524 #[command(subcommand)]
525 pub command: WalletAction,
526}
527
528#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
529pub struct WalletNewArgs {
530 #[arg(long = "format", verbatim_doc_comment)]
532 pub wallet_format: Option<String>,
533
534 #[arg(long = "outfile", verbatim_doc_comment)]
536 pub outfile: Option<String>,
537
538 #[arg(long = "hrp", verbatim_doc_comment)]
539 pub hrp: Option<String>,
540}
541
542#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
543pub struct WalletConvertArgs {
544 #[arg(long = "in-format", verbatim_doc_comment)]
545 pub from: String,
546
547 #[arg(long = "out-format", verbatim_doc_comment)]
548 pub to: String,
549
550 #[arg(long = "infile", verbatim_doc_comment)]
551 pub infile: Option<String>,
552
553 #[arg(long = "outfile", verbatim_doc_comment)]
554 pub outfile: Option<String>,
555
556 #[arg(long = "hrp", verbatim_doc_comment)]
557 pub hrp: Option<String>,
558}
559
560#[derive(Default, Clone, PartialEq, Eq, Debug, Args)]
561pub struct WalletBech32Args {
562 #[arg(long = "encode", verbatim_doc_comment)]
563 pub hex_address: Option<String>,
564 #[arg(long = "decode", verbatim_doc_comment)]
565 pub bech32_address: Option<String>,
566}