@@ -46,8 +46,9 @@ impl AppConfig {
46
46
config. configuration_directory . clone_from ( config_dir) ;
47
47
}
48
48
49
- config. configuration_directory =
50
- cli. config_dir . clone ( ) . unwrap_or ( PathBuf :: from ( "./sqlpage" ) ) ;
49
+ if let Some ( config_dir) = & cli. config_dir {
50
+ config. configuration_directory . clone_from ( config_dir) ;
51
+ }
51
52
52
53
config. configuration_directory = std:: fs:: canonicalize ( & config. configuration_directory )
53
54
. unwrap_or_else ( |_| config. configuration_directory . clone ( ) ) ;
@@ -65,6 +66,9 @@ impl AppConfig {
65
66
}
66
67
67
68
config. validate ( ) ?;
69
+
70
+ log:: debug!( "Loaded configuration: {:#?}" , config) ;
71
+
68
72
Ok ( config)
69
73
}
70
74
@@ -282,7 +286,6 @@ pub fn load_from_file(config_file: &Path) -> anyhow::Result<AppConfig> {
282
286
let app_config = config
283
287
. try_deserialize :: < AppConfig > ( )
284
288
. with_context ( || "Unable to load configuration" ) ?;
285
- log:: debug!( "Loaded configuration: {:#?}" , app_config) ;
286
289
Ok ( app_config)
287
290
}
288
291
@@ -479,6 +482,10 @@ pub mod tests {
479
482
#[ cfg( test) ]
480
483
mod test {
481
484
use super :: * ;
485
+ use std:: env;
486
+ use std:: sync:: Mutex ;
487
+
488
+ static ENV_LOCK : Mutex < ( ) > = Mutex :: new ( ( ) ) ;
482
489
483
490
#[ test]
484
491
fn test_default_site_prefix ( ) {
@@ -510,21 +517,151 @@ mod test {
510
517
}
511
518
512
519
#[ test]
513
- fn test_cli ( ) {
520
+ fn test_cli_argument_parsing ( ) {
514
521
let cli = Cli :: parse_from ( & [
515
522
"sqlpage" ,
516
523
"--web-root" ,
517
524
"/path/to/web" ,
518
525
"--config-dir" ,
519
- "custom_config" ,
526
+ "/path/to/config" ,
527
+ "--config-file" ,
528
+ "/path/to/config.json" ,
520
529
] ) ;
530
+
521
531
assert_eq ! ( cli. web_root, Some ( PathBuf :: from( "/path/to/web" ) ) ) ;
522
- assert_eq ! ( cli. config_dir, Some ( PathBuf :: from( "custom_config" ) ) ) ;
532
+ assert_eq ! ( cli. config_dir, Some ( PathBuf :: from( "/path/to/config" ) ) ) ;
533
+ assert_eq ! ( cli. config_file, Some ( PathBuf :: from( "/path/to/config.json" ) ) ) ;
534
+ }
535
+
536
+ #[ test]
537
+ fn test_sqlpage_prefixed_env_variable_parsing ( ) {
538
+ let _lock = ENV_LOCK
539
+ . lock ( )
540
+ . expect ( "Another test panicked while holding the lock" ) ;
541
+ env:: set_var ( "SQLPAGE_CONFIGURATION_DIRECTORY" , "/path/to/config" ) ;
542
+
543
+ let config = load_from_env ( ) . unwrap ( ) ;
544
+
545
+ assert_eq ! (
546
+ config. configuration_directory,
547
+ PathBuf :: from( "/path/to/config" ) ,
548
+ "Configuration directory should match the SQLPAGE_CONFIGURATION_DIRECTORY env var"
549
+ ) ;
550
+
551
+ env:: remove_var ( "SQLPAGE_CONFIGURATION_DIRECTORY" ) ;
552
+ }
553
+
554
+ #[ test]
555
+ fn test_config_priority ( ) {
556
+ let _lock = ENV_LOCK
557
+ . lock ( )
558
+ . expect ( "Another test panicked while holding the lock" ) ;
559
+ env:: set_var ( "SQLPAGE_WEB_ROOT" , "/" ) ;
560
+
561
+ let cli = Cli {
562
+ web_root : Some ( PathBuf :: from ( "." ) ) ,
563
+ config_dir : None ,
564
+ config_file : None ,
565
+ } ;
566
+
567
+ let config = AppConfig :: from_cli ( & cli) . unwrap ( ) ;
568
+
569
+ assert_eq ! (
570
+ config. web_root,
571
+ PathBuf :: from( "." ) ,
572
+ "CLI argument should take precedence over environment variable"
573
+ ) ;
574
+
575
+ env:: remove_var ( "SQLPAGE_WEB_ROOT" ) ;
576
+ }
577
+
578
+ #[ test]
579
+ fn test_config_file_priority ( ) {
580
+ let _lock = ENV_LOCK
581
+ . lock ( )
582
+ . expect ( "Another test panicked while holding the lock" ) ;
583
+ let temp_dir = std:: env:: temp_dir ( ) . join ( "sqlpage_test" ) ;
584
+ std:: fs:: create_dir_all ( & temp_dir) . unwrap ( ) ;
585
+ let config_file_path = temp_dir. join ( "sqlpage.json" ) ;
586
+ let config_web_dir = temp_dir. join ( "config/web" ) ;
587
+ let env_web_dir = temp_dir. join ( "env/web" ) ;
588
+ let cli_web_dir = temp_dir. join ( "cli/web" ) ;
589
+ std:: fs:: create_dir_all ( & config_web_dir) . unwrap ( ) ;
590
+ std:: fs:: create_dir_all ( & env_web_dir) . unwrap ( ) ;
591
+ std:: fs:: create_dir_all ( & cli_web_dir) . unwrap ( ) ;
592
+
593
+ let config_content = format ! (
594
+ r#"{{ "web_root": "{}" }}"# ,
595
+ config_web_dir. to_str( ) . unwrap( )
596
+ ) ;
597
+ std:: fs:: write ( & config_file_path, config_content) . unwrap ( ) ;
598
+
599
+ env:: set_var ( "SQLPAGE_WEB_ROOT" , env_web_dir. to_str ( ) . unwrap ( ) ) ;
600
+
601
+ let cli = Cli {
602
+ web_root : None ,
603
+ config_dir : None ,
604
+ config_file : Some ( config_file_path. clone ( ) ) ,
605
+ } ;
606
+
607
+ let config = AppConfig :: from_cli ( & cli) . unwrap ( ) ;
608
+
609
+ assert_eq ! (
610
+ config. web_root, env_web_dir,
611
+ "Environment variable should override config file"
612
+ ) ;
613
+ assert_eq ! (
614
+ config. configuration_directory,
615
+ cannonicalize_if_possible( & PathBuf :: from( "./sqlpage" ) ) ,
616
+ "Configuration directory should be default when not overridden"
617
+ ) ;
618
+
619
+ let cli_with_web_root = Cli {
620
+ web_root : Some ( cli_web_dir. clone ( ) ) ,
621
+ config_dir : None ,
622
+ config_file : Some ( config_file_path) ,
623
+ } ;
624
+
625
+ let config = AppConfig :: from_cli ( & cli_with_web_root) . unwrap ( ) ;
626
+ assert_eq ! (
627
+ config. web_root, cli_web_dir,
628
+ "CLI argument should take precedence over environment variable and config file"
629
+ ) ;
630
+ assert_eq ! (
631
+ config. configuration_directory,
632
+ cannonicalize_if_possible( & PathBuf :: from( "./sqlpage" ) ) ,
633
+ "Configuration directory should remain unchanged"
634
+ ) ;
635
+
636
+ env:: remove_var ( "SQLPAGE_WEB_ROOT" ) ;
637
+ std:: fs:: remove_dir_all ( & temp_dir) . unwrap ( ) ;
523
638
}
524
639
525
640
#[ test]
526
- fn verify_cli ( ) {
527
- use clap:: CommandFactory ;
528
- Cli :: command ( ) . debug_assert ( ) ;
641
+ fn test_default_values ( ) {
642
+ let _lock = ENV_LOCK
643
+ . lock ( )
644
+ . expect ( "Another test panicked while holding the lock" ) ;
645
+ env:: remove_var ( "SQLPAGE_CONFIGURATION_DIRECTORY" ) ;
646
+ env:: remove_var ( "SQLPAGE_WEB_ROOT" ) ;
647
+
648
+ let cli = Cli {
649
+ web_root : None ,
650
+ config_dir : None ,
651
+ config_file : None ,
652
+ } ;
653
+
654
+ let config = AppConfig :: from_cli ( & cli) . unwrap ( ) ;
655
+
656
+ assert_eq ! (
657
+ config. web_root,
658
+ default_web_root( ) ,
659
+ "Web root should default to current directory when not specified"
660
+ ) ;
661
+ assert_eq ! (
662
+ config. configuration_directory,
663
+ cannonicalize_if_possible( & PathBuf :: from( "./sqlpage" ) ) ,
664
+ "Configuration directory should default to ./sqlpage when not specified"
665
+ ) ;
529
666
}
530
667
}
0 commit comments