1
1
use std:: env;
2
+ use std:: ffi:: OsString ;
2
3
use std:: sync:: Arc ;
3
4
4
- use clap:: Parser ;
5
+ use clap:: { Parser , Subcommand } ;
5
6
use comfy_table:: { Attribute , Cell , ContentArrangement , Table , presets} ;
6
7
use errors:: CliError ;
7
8
use miden_client:: account:: AccountHeader ;
@@ -38,7 +39,24 @@ mod utils;
38
39
const CLIENT_CONFIG_FILE_NAME : & str = "miden-client.toml" ;
39
40
40
41
/// Client binary name.
41
- pub const CLIENT_BINARY_NAME : & str = "miden-client" ;
42
+ /// Note: If, for whatever reason, we fail to obtain the client's executable
43
+ /// name, then we simply display the standard "miden-client".
44
+ pub fn client_binary_name ( ) -> OsString {
45
+ std:: env:: current_exe ( )
46
+ . map ( |executable| {
47
+ executable
48
+ . file_name ( )
49
+ . expect ( "ERROR: failed to obtain the executable's file name" )
50
+ . to_os_string ( )
51
+ } )
52
+ . inspect_err ( |e| {
53
+ eprintln ! (
54
+ "WARNING: Couldn't obtain the name of the current executable because of {e}.\
55
+ Defaulting to miden-client."
56
+ ) ;
57
+ } )
58
+ . unwrap_or ( OsString :: from ( "miden-client" ) )
59
+ }
42
60
43
61
/// Number of blocks that must elapse after a transaction’s reference block before it is marked
44
62
/// stale and discarded.
@@ -52,14 +70,53 @@ const TX_GRACEFUL_BLOCK_DELTA: u32 = 20;
52
70
version,
53
71
rename_all = "kebab-case"
54
72
) ]
55
- pub struct Cli {
73
+ #[ command( multicall( true ) ) ]
74
+ pub struct MidenClientCli {
56
75
#[ command( subcommand) ]
57
- action : Command ,
76
+ behavior : Behavior ,
77
+ }
78
+
79
+ impl From < MidenClientCli > for Cli {
80
+ fn from ( value : MidenClientCli ) -> Self {
81
+ match value. behavior {
82
+ Behavior :: MidenClient { cli } => cli,
83
+ Behavior :: External ( args) => Cli :: parse_from ( args) . set_external ( ) ,
84
+ }
85
+ }
86
+ }
58
87
88
+ #[ derive( Debug , Subcommand ) ]
89
+ #[ command( rename_all = "kebab-case" ) ]
90
+ enum Behavior {
91
+ /// The Miden toolchain installer
92
+ MidenClient {
93
+ #[ command( flatten) ]
94
+ cli : Cli ,
95
+ } ,
96
+
97
+ /// Used when the Miden Client CLI is called under a different name, like it
98
+ /// is the case in [Midenup](https://github.com/0xMiden/midenup).
99
+ #[ command( external_subcommand) ]
100
+ External ( Vec < OsString > ) ,
101
+ }
102
+
103
+ #[ derive( Parser , Debug ) ]
104
+ #[ command( name = "miden-client" ) ]
105
+ pub struct Cli {
59
106
/// Activates the executor's debug mode, which enables debug output for scripts
60
107
/// that were compiled and executed with this mode.
61
108
#[ arg( short, long, default_value_t = false ) ]
62
109
debug : bool ,
110
+
111
+ #[ command( subcommand) ]
112
+ action : Command ,
113
+
114
+ /// Indicates whether the client's CLI is being called directly, or
115
+ /// externally under an alias (like in the case of
116
+ /// [Midenup](https://github.com/0xMiden/midenup).
117
+ #[ arg( skip) ]
118
+ #[ allow( unused) ]
119
+ external : bool ,
63
120
}
64
121
65
122
/// CLI actions.
@@ -150,6 +207,11 @@ impl Cli {
150
207
Command :: ConsumeNotes ( consume_notes) => consume_notes. execute ( client) . await ,
151
208
}
152
209
}
210
+
211
+ fn set_external ( mut self ) -> Self {
212
+ self . external = true ;
213
+ self
214
+ }
153
215
}
154
216
155
217
pub fn create_dynamic_table ( headers : & [ & str ] ) -> Table {
0 commit comments