1use std::path::PathBuf;
2
3use clap::{Args, Parser, Subcommand};
4
5#[derive(Debug, Parser)]
6#[command(about = "A cashu mint written in rust", author = env!("CARGO_PKG_AUTHORS"), version = env!("CARGO_PKG_VERSION"))]
7pub struct CLIArgs {
8 #[arg(
9 short,
10 long,
11 help = "Use the <directory> as the location of the database",
12 required = false
13 )]
14 pub work_dir: Option<PathBuf>,
15 #[cfg(feature = "sqlcipher")]
16 #[arg(
17 short,
18 long,
19 global = true,
20 help = "Database password for SQLCipher (required when opening an encrypted database)"
21 )]
22 pub password: Option<String>,
23 #[arg(
24 short,
25 long,
26 global = true,
27 help = "Legacy startup flag; use `config init` or `config apply` instead",
28 required = false
29 )]
30 pub config: Option<PathBuf>,
31 #[arg(
32 long,
33 global = true,
34 help = "Legacy seed file; accepted only by `config migrate`",
35 required = false
36 )]
37 pub seed_file: Option<PathBuf>,
38 #[arg(
39 long,
40 help = "Enable logging output",
41 required = false,
42 action = clap::ArgAction::SetTrue,
43 default_value = "true"
44 )]
45 pub enable_logging: bool,
46 #[command(subcommand)]
47 pub command: Option<Commands>,
48}
49
50#[derive(Debug, Subcommand)]
52pub enum Commands {
53 Config(ConfigArgs),
55}
56
57#[derive(Debug, Args)]
59pub struct ConfigArgs {
60 #[command(subcommand)]
61 pub command: ConfigCommands,
62}
63
64#[derive(Debug, Subcommand)]
66pub enum ConfigCommands {
67 Migrate(MigrateConfigArgs),
69 Init(ConfigFileArgs),
71 Validate(ConfigFileArgs),
73 Apply(ApplyConfigArgs),
75 Rollback,
77 Show,
79 Export(ExportConfigArgs),
81}
82
83#[derive(Debug, Args)]
85pub struct MigrateConfigArgs {
86 #[arg(long)]
88 pub file: PathBuf,
89 #[arg(long)]
91 pub output: PathBuf,
92 #[arg(long)]
94 pub secrets_dir: Option<PathBuf>,
95 #[arg(long)]
97 pub force: bool,
98}
99
100#[derive(Debug, Args)]
102pub struct ConfigFileArgs {
103 #[arg(long)]
105 pub file: PathBuf,
106}
107
108#[derive(Debug, Args)]
110pub struct ExportConfigArgs {
111 #[arg(long)]
113 pub file: PathBuf,
114 #[arg(long)]
116 pub force: bool,
117}
118
119#[derive(Debug, Args)]
121pub struct ApplyConfigArgs {
122 #[arg(long)]
124 pub file: PathBuf,
125 #[arg(long)]
127 pub validate_only: bool,
128}
129
130#[cfg(test)]
131mod tests {
132 use super::*;
133
134 #[test]
135 fn parses_configuration_commands() {
136 for command in ["init", "validate"] {
137 CLIArgs::try_parse_from(["cdk-mintd", "config", command, "--file", "/tmp/mint.toml"])
138 .expect("configuration command should parse");
139 }
140
141 let args =
142 CLIArgs::try_parse_from(["cdk-mintd", "config", "export", "--file", "/tmp/mint.toml"])
143 .expect("configuration export should parse");
144 assert!(matches!(
145 args.command,
146 Some(Commands::Config(ConfigArgs {
147 command: ConfigCommands::Export(ExportConfigArgs { force: false, .. }),
148 }))
149 ));
150
151 let args = CLIArgs::try_parse_from([
152 "cdk-mintd",
153 "config",
154 "export",
155 "--file",
156 "/tmp/mint.toml",
157 "--force",
158 ])
159 .expect("configuration export should parse");
160 assert!(matches!(
161 args.command,
162 Some(Commands::Config(ConfigArgs {
163 command: ConfigCommands::Export(ExportConfigArgs { force: true, .. }),
164 }))
165 ));
166
167 CLIArgs::try_parse_from([
168 "cdk-mintd",
169 "config",
170 "apply",
171 "--file",
172 "/tmp/mint.toml",
173 "--validate-only",
174 ])
175 .expect("configuration apply should parse");
176 CLIArgs::try_parse_from(["cdk-mintd", "config", "show"])
177 .expect("configuration show should parse");
178 CLIArgs::try_parse_from(["cdk-mintd", "config", "rollback"])
179 .expect("configuration rollback should parse");
180
181 let args = CLIArgs::try_parse_from([
182 "cdk-mintd",
183 "config",
184 "migrate",
185 "--file",
186 "/tmp/legacy.toml",
187 "--output",
188 "/tmp/migrated.toml",
189 "--secrets-dir",
190 "/tmp/mint-secrets",
191 ])
192 .expect("configuration migration should parse");
193 assert!(matches!(
194 args.command,
195 Some(Commands::Config(ConfigArgs {
196 command: ConfigCommands::Migrate(MigrateConfigArgs { force: false, .. }),
197 }))
198 ));
199
200 let args = CLIArgs::try_parse_from([
201 "cdk-mintd",
202 "--seed-file",
203 "/tmp/seed.txt",
204 "config",
205 "migrate",
206 "--file",
207 "/tmp/legacy.toml",
208 "--output",
209 "/tmp/migrated.toml",
210 ])
211 .expect("legacy seed-file migration should parse");
212 assert_eq!(args.seed_file, Some(PathBuf::from("/tmp/seed.txt")));
213 }
214
215 #[test]
216 fn no_subcommand_still_parses_daemon_startup() {
217 let args = CLIArgs::try_parse_from(["cdk-mintd"]).expect("daemon arguments should parse");
218 assert!(args.command.is_none());
219 }
220}