@@ -75,15 +75,15 @@ struct CLIArgs {
7575 std::string sim_file;
7676 bool nogui = false ;
7777 bool log = false ;
78- bool nobanner = false ; // NEW: Disable banner display
79- bool quiet = false ; // NEW: Quiet mode (minimal output)
80- bool debug = false ; // NEW: Enable detailed simulation diagnostics
81- bool trace = false ; // NEW: Enable step-by-step simulation tracing
82- std::string output_h5; // NEW: Export HDF5 results path
83- bool h5_verbose = false ; // NEW: HDF5 verbose diagnostics
84- std::string h5_tag; // NEW: Optional tag appended to filename
85- bool fail_fast = false ; // NEW: Stop on first failure during sweep
86- bool profile = false ; // NEW: Enable runtime profiling summary
78+ bool nobanner = false ; // Disable banner display
79+ bool quiet = false ; // Quiet mode (minimal output)
80+ bool debug = false ; // Enable detailed simulation diagnostics
81+ bool trace = false ; // Enable step-by-step simulation tracing
82+ std::string output_h5; // Export HDF5 results path
83+ bool h5_verbose = false ; // HDF5 verbose diagnostics
84+ std::string h5_tag; // Optional tag appended to filename
85+ bool fail_fast = false ; // Stop on first failure during sweep
86+ bool profile = false ; // Enable runtime profiling summary
8787};
8888
8989static CLIArgs ParseArguments (int argc, char * argv[]) {
@@ -166,49 +166,50 @@ int main(int argc, char* argv[]) {
166166#ifdef _WIN32
167167 // Enable UTF-8 console output on Windows
168168 SetConsoleOutputCP (CP_UTF8);
169- std::ios_base::sync_with_stdio (false );
170169#endif
171170
172171 // Check for hidden options first (before any other processing)
173172 if (hydroc::misc::HandleHiddenOptions (argc, argv)) {
174173 return 0 ;
175174 }
176175
176+ // -------------------------------------------------------------------------
177+ // Initialize logging early so all CLI output uses the nice formatting
178+ // -------------------------------------------------------------------------
179+ hydroc::LoggingConfig cfg;
180+ cfg.enable_cli_output = true ;
181+ cfg.enable_file_output = false ;
182+ cfg.console_level = hydroc::LogLevel::Info;
183+ cfg.file_level = hydroc::LogLevel::Info;
184+ hydroc::Initialize (cfg);
185+
177186 // Check for help/version/info flags first (before requiring input directory)
178187 for (int i = 1 ; i < argc; i++) {
179188 std::string arg = argv[i];
180189 if (arg == " --help" || arg == " -h" ) {
181- hydroc::LoggingConfig cfg;
182- cfg.enable_cli_output = true ;
183- cfg.enable_file_output = false ;
184- cfg.console_level = hydroc::LogLevel::Info;
185- cfg.file_level = hydroc::LogLevel::Info;
186- hydroc::Initialize (cfg);
187190 PrintHelp (argv[0 ]);
188191 hydroc::Shutdown ();
189192 return 0 ;
190193 } else if (arg == " --version" || arg == " -v" ) {
191- hydroc::LoggingConfig cfg;
192- cfg.enable_cli_output = true ;
193- cfg.enable_file_output = false ;
194- cfg.console_level = hydroc::LogLevel::Info;
195- cfg.file_level = hydroc::LogLevel::Info;
196- hydroc::Initialize (cfg);
197194 PrintVersion ();
198195 hydroc::Shutdown ();
199196 return 0 ;
200197 } else if (arg == " --info" || arg == " -i" ) {
201- hydroc::LoggingConfig cfg;
202- cfg.enable_cli_output = true ;
203- cfg.enable_file_output = false ;
204- cfg.console_level = hydroc::LogLevel::Info;
205- cfg.file_level = hydroc::LogLevel::Info;
206- hydroc::Initialize (cfg);
207198 PrintInfo ();
208199 hydroc::Shutdown ();
209200 return 0 ;
210201 }
211202 }
203+
204+ // Handle "no arguments" case
205+ if (argc == 1 ) {
206+ hydroc::cli::LogError (" ERROR: Input directory or setup file is required" );
207+ hydroc::cli::ShowEmptyLine ();
208+ hydroc::cli::LogInfo (std::string (" Usage: " ) + argv[0 ] + " [options] <input_directory_or_setup_file>" );
209+ hydroc::cli::LogInfo (" Use --help for more information." );
210+ hydroc::Shutdown ();
211+ return 1 ;
212+ }
212213
213214 // Parse command line arguments
214215 CLIArgs args = ParseArguments (argc, argv);
@@ -219,85 +220,61 @@ int main(int argc, char* argv[]) {
219220 hydroc::cli::ShowEmptyLine ();
220221 hydroc::cli::LogInfo (std::string (" Usage: " ) + argv[0 ] + " [options] <input_directory_or_setup_file>" );
221222 hydroc::cli::LogInfo (" Use --help for more information." );
223+ hydroc::Shutdown ();
222224 return 1 ;
223225 }
224226
225227 // Check if input is a setup file or directory
226228 std::filesystem::path input_path (args.input_directory );
227229 if (std::filesystem::exists (input_path)) {
228230 if (std::filesystem::is_regular_file (input_path)) {
229- // Check if it's a setup file
230231 if (input_path.extension () == " .yaml" ) {
231232 const std::string filename = input_path.filename ().string ();
232233 const std::string suffix = " .setup.yaml" ;
233234 if (filename.length () >= suffix.length () &&
234235 filename.compare (filename.length () - suffix.length (), suffix.length (), suffix) == 0 ) {
235- // Convert setup file path to directory path
236236 args.input_directory = input_path.parent_path ().string ();
237237 hydroc::cli::LogInfo (std::string (" Loaded setup file: " ) + input_path.string ());
238238 } else {
239239 hydroc::cli::LogError (" ERROR: File provided is not a valid .setup.yaml file" );
240240 hydroc::cli::LogInfo (std::string (" Path: " ) + args.input_directory );
241241 hydroc::cli::LogInfo (" Expected: Directory or any file ending in '.setup.yaml'" );
242+ hydroc::Shutdown ();
242243 return 1 ;
243244 }
244245 }
245246 } else if (!std::filesystem::is_directory (input_path)) {
246247 hydroc::cli::LogError (" ERROR: Path is neither a directory nor a regular file" );
247248 hydroc::cli::LogInfo (std::string (" Path: " ) + args.input_directory );
249+ hydroc::Shutdown ();
248250 return 1 ;
249251 }
250252 } else {
251253 hydroc::cli::LogError (" ERROR: Input path does not exist" );
252254 hydroc::cli::LogInfo (std::string (" Path: " ) + args.input_directory );
255+ hydroc::Shutdown ();
253256 return 1 ;
254257 }
255258
256- // Note: Banner will be rendered by the YAML runner
259+ // Shutdown logging - the runner will reinitialize it
260+ hydroc::Shutdown ();
257261
258262 // Prepare arguments for the YAML runner
259263 std::vector<std::string> runner_args;
260- runner_args.push_back (argv[0 ]); // program name
261-
262- // Add input directory
264+ runner_args.push_back (argv[0 ]);
263265 runner_args.push_back (args.input_directory );
264266
265- // Add optional flags
266- if (args.nogui ) {
267- runner_args.push_back (" --nogui" );
268- }
269-
270- // Add logging flag if requested
271- if (args.log ) {
272- runner_args.push_back (" --log" );
273- }
274-
275- // Add new CLI options
276- if (args.nobanner ) {
277- runner_args.push_back (" --nobanner" );
278- }
279-
280- if (args.quiet ) {
281- runner_args.push_back (" --quiet" );
282- }
283-
284- if (args.debug ) {
285- runner_args.push_back (" --debug" );
286- }
287-
288- if (args.trace ) {
289- runner_args.push_back (" --trace" );
290- }
291-
292- if (args.profile ) {
293- runner_args.push_back (" --profile" );
294- }
295-
267+ if (args.nogui ) runner_args.push_back (" --nogui" );
268+ if (args.log ) runner_args.push_back (" --log" );
269+ if (args.nobanner ) runner_args.push_back (" --nobanner" );
270+ if (args.quiet ) runner_args.push_back (" --quiet" );
271+ if (args.debug ) runner_args.push_back (" --debug" );
272+ if (args.trace ) runner_args.push_back (" --trace" );
273+ if (args.profile ) runner_args.push_back (" --profile" );
296274 if (!args.model_file .empty ()) {
297275 runner_args.push_back (" --model_file" );
298276 runner_args.push_back (args.model_file );
299277 }
300-
301278 if (!args.sim_file .empty ()) {
302279 runner_args.push_back (" --sim_file" );
303280 runner_args.push_back (args.sim_file );
@@ -306,9 +283,7 @@ int main(int argc, char* argv[]) {
306283 runner_args.push_back (" --output-h5" );
307284 runner_args.push_back (args.output_h5 );
308285 }
309- if (args.fail_fast ) {
310- runner_args.push_back (" --fail-fast" );
311- }
286+ if (args.fail_fast ) runner_args.push_back (" --fail-fast" );
312287
313288 // Convert to argc/argv format for the runner
314289 std::vector<char *> runner_argv;
0 commit comments