1414
1515use std:: collections:: HashSet ;
1616
17+ use camino:: Utf8PathBuf ;
1718use clap:: Parser ;
1819use mas_config:: { ConfigurationSection , RootConfig , SyncConfig } ;
1920use mas_storage:: {
@@ -23,6 +24,7 @@ use mas_storage::{
2324use mas_storage_pg:: PgRepository ;
2425use rand:: SeedableRng ;
2526use sqlx:: { postgres:: PgAdvisoryLock , Acquire } ;
27+ use tokio:: io:: AsyncWriteExt ;
2628use tracing:: { error, info, info_span, warn} ;
2729
2830use crate :: util:: database_connection_from_config;
@@ -94,7 +96,13 @@ enum Subcommand {
9496 Check ,
9597
9698 /// Generate a new config file
97- Generate ,
99+ Generate {
100+ /// The path to the config file to generate
101+ ///
102+ /// If not specified, the config will be written to stdout
103+ #[ clap( short, long) ]
104+ output : Option < Utf8PathBuf > ,
105+ } ,
98106
99107 /// Sync the clients and providers from the config file to the database
100108 Sync {
@@ -128,14 +136,22 @@ impl Options {
128136 info ! ( path = ?root. config, "Configuration file looks good" ) ;
129137 }
130138
131- SC :: Generate => {
139+ SC :: Generate { output } => {
132140 let _span = info_span ! ( "cli.config.generate" ) . entered ( ) ;
133141
134142 // XXX: we should disallow SeedableRng::from_entropy
135143 let rng = rand_chacha:: ChaChaRng :: from_entropy ( ) ;
136144 let config = RootConfig :: load_and_generate ( rng) . await ?;
137-
138- serde_yaml:: to_writer ( std:: io:: stdout ( ) , & config) ?;
145+ let config = serde_yaml:: to_string ( & config) ?;
146+
147+ if let Some ( output) = output {
148+ info ! ( "Writing configuration to {output:?}" ) ;
149+ let mut file = tokio:: fs:: File :: create ( output) . await ?;
150+ file. write_all ( config. as_bytes ( ) ) . await ?;
151+ } else {
152+ info ! ( "Writing configuration to standard output" ) ;
153+ tokio:: io:: stdout ( ) . write_all ( config. as_bytes ( ) ) . await ?;
154+ }
139155 }
140156
141157 SC :: Sync { prune, dry_run } => {
0 commit comments