1
1
use std:: collections:: BTreeSet ;
2
- use std:: env;
3
2
use std:: fs:: { File , remove_file} ;
4
3
use std:: io:: Write ;
5
- use std:: path:: Path ;
4
+ use std:: path:: { Path , PathBuf } ;
5
+ use std:: { env, fs} ;
6
6
7
7
use build_helper:: ci:: CiEnv ;
8
8
use clap:: CommandFactory ;
@@ -23,6 +23,27 @@ pub(crate) fn parse(config: &str) -> Config {
23
23
)
24
24
}
25
25
26
+ fn get_toml ( file : & Path ) -> Result < TomlConfig , toml:: de:: Error > {
27
+ let contents = std:: fs:: read_to_string ( file) . unwrap ( ) ;
28
+ toml:: from_str ( & contents) . and_then ( |table : toml:: Value | TomlConfig :: deserialize ( table) )
29
+ }
30
+
31
+ /// Helps with debugging by using consistent test-specific directories instead of
32
+ /// random temporary directories.
33
+ fn prepare_test_specific_dir ( ) -> PathBuf {
34
+ let current = std:: thread:: current ( ) ;
35
+ // Replace "::" with "_" to make it safe for directory names on Windows systems
36
+ let test_path = current. name ( ) . unwrap ( ) . replace ( "::" , "_" ) ;
37
+
38
+ let testdir = parse ( "" ) . tempdir ( ) . join ( test_path) ;
39
+
40
+ // clean up any old test files
41
+ let _ = fs:: remove_dir_all ( & testdir) ;
42
+ let _ = fs:: create_dir_all ( & testdir) ;
43
+
44
+ testdir
45
+ }
46
+
26
47
#[ test]
27
48
fn download_ci_llvm ( ) {
28
49
let config = parse ( "llvm.download-ci-llvm = false" ) ;
@@ -539,3 +560,188 @@ fn test_ci_flag() {
539
560
let config = Config :: parse_inner ( Flags :: parse ( & [ "check" . into ( ) ] ) , |& _| toml:: from_str ( "" ) ) ;
540
561
assert_eq ! ( config. is_running_on_ci, CiEnv :: is_ci( ) ) ;
541
562
}
563
+
564
+ #[ test]
565
+ fn test_precedence_of_includes ( ) {
566
+ let testdir = prepare_test_specific_dir ( ) ;
567
+
568
+ let root_config = testdir. join ( "config.toml" ) ;
569
+ let root_config_content = br#"
570
+ include = ["./extension.toml"]
571
+
572
+ [llvm]
573
+ link-jobs = 2
574
+ "# ;
575
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content) . unwrap ( ) ;
576
+
577
+ let extension = testdir. join ( "extension.toml" ) ;
578
+ let extension_content = br#"
579
+ change-id=543
580
+ include = ["./extension2.toml"]
581
+ "# ;
582
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
583
+
584
+ let extension = testdir. join ( "extension2.toml" ) ;
585
+ let extension_content = br#"
586
+ change-id=742
587
+
588
+ [llvm]
589
+ link-jobs = 10
590
+
591
+ [build]
592
+ description = "Some creative description"
593
+ "# ;
594
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
595
+
596
+ let config = Config :: parse_inner (
597
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
598
+ get_toml,
599
+ ) ;
600
+
601
+ assert_eq ! ( config. change_id. unwrap( ) , ChangeId :: Id ( 543 ) ) ;
602
+ assert_eq ! ( config. llvm_link_jobs. unwrap( ) , 2 ) ;
603
+ assert_eq ! ( config. description. unwrap( ) , "Some creative description" ) ;
604
+ }
605
+
606
+ #[ test]
607
+ #[ should_panic( expected = "Cyclic inclusion detected" ) ]
608
+ fn test_cyclic_include_direct ( ) {
609
+ let testdir = prepare_test_specific_dir ( ) ;
610
+
611
+ let root_config = testdir. join ( "config.toml" ) ;
612
+ let root_config_content = br#"
613
+ include = ["./extension.toml"]
614
+ "# ;
615
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content) . unwrap ( ) ;
616
+
617
+ let extension = testdir. join ( "extension.toml" ) ;
618
+ let extension_content = br#"
619
+ include = ["./config.toml"]
620
+ "# ;
621
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
622
+
623
+ let config = Config :: parse_inner (
624
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
625
+ get_toml,
626
+ ) ;
627
+ }
628
+
629
+ #[ test]
630
+ #[ should_panic( expected = "Cyclic inclusion detected" ) ]
631
+ fn test_cyclic_include_indirect ( ) {
632
+ let testdir = prepare_test_specific_dir ( ) ;
633
+
634
+ let root_config = testdir. join ( "config.toml" ) ;
635
+ let root_config_content = br#"
636
+ include = ["./extension.toml"]
637
+ "# ;
638
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content) . unwrap ( ) ;
639
+
640
+ let extension = testdir. join ( "extension.toml" ) ;
641
+ let extension_content = br#"
642
+ include = ["./extension2.toml"]
643
+ "# ;
644
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
645
+
646
+ let extension = testdir. join ( "extension2.toml" ) ;
647
+ let extension_content = br#"
648
+ include = ["./extension3.toml"]
649
+ "# ;
650
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
651
+
652
+ let extension = testdir. join ( "extension3.toml" ) ;
653
+ let extension_content = br#"
654
+ include = ["./extension.toml"]
655
+ "# ;
656
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
657
+
658
+ let config = Config :: parse_inner (
659
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
660
+ get_toml,
661
+ ) ;
662
+ }
663
+
664
+ #[ test]
665
+ fn test_include_absolute_paths ( ) {
666
+ let testdir = prepare_test_specific_dir ( ) ;
667
+
668
+ let extension = testdir. join ( "extension.toml" ) ;
669
+ File :: create ( & extension) . unwrap ( ) . write_all ( & [ ] ) . unwrap ( ) ;
670
+
671
+ let root_config = testdir. join ( "config.toml" ) ;
672
+ let root_config_content =
673
+ format ! ( r#"include = ["{}"]"# , extension. canonicalize( ) . unwrap( ) . to_str( ) . unwrap( ) ) ;
674
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content. as_bytes ( ) ) . unwrap ( ) ;
675
+
676
+ let config = Config :: parse_inner (
677
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
678
+ get_toml,
679
+ ) ;
680
+ }
681
+
682
+ #[ test]
683
+ fn test_include_relative_paths ( ) {
684
+ let testdir = prepare_test_specific_dir ( ) ;
685
+
686
+ let _ = fs:: create_dir_all ( & testdir. join ( "subdir/another_subdir" ) ) ;
687
+
688
+ let root_config = testdir. join ( "config.toml" ) ;
689
+ let root_config_content = br#"
690
+ include = ["./subdir/extension.toml"]
691
+ "# ;
692
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content) . unwrap ( ) ;
693
+
694
+ let extension = testdir. join ( "subdir/extension.toml" ) ;
695
+ let extension_content = br#"
696
+ include = ["../extension2.toml"]
697
+ "# ;
698
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
699
+
700
+ let extension = testdir. join ( "extension2.toml" ) ;
701
+ let extension_content = br#"
702
+ include = ["./subdir/another_subdir/extension3.toml"]
703
+ "# ;
704
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
705
+
706
+ let extension = testdir. join ( "subdir/another_subdir/extension3.toml" ) ;
707
+ let extension_content = br#"
708
+ include = ["../../extension4.toml"]
709
+ "# ;
710
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
711
+
712
+ let extension = testdir. join ( "extension4.toml" ) ;
713
+ File :: create ( extension) . unwrap ( ) . write_all ( & [ ] ) . unwrap ( ) ;
714
+
715
+ let config = Config :: parse_inner (
716
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
717
+ get_toml,
718
+ ) ;
719
+ }
720
+
721
+ #[ test]
722
+ fn test_include_precedence_over_profile ( ) {
723
+ let testdir = prepare_test_specific_dir ( ) ;
724
+
725
+ let root_config = testdir. join ( "config.toml" ) ;
726
+ let root_config_content = br#"
727
+ profile = "dist"
728
+ include = ["./extension.toml"]
729
+ "# ;
730
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content) . unwrap ( ) ;
731
+
732
+ let extension = testdir. join ( "extension.toml" ) ;
733
+ let extension_content = br#"
734
+ [rust]
735
+ channel = "dev"
736
+ "# ;
737
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
738
+
739
+ let config = Config :: parse_inner (
740
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
741
+ get_toml,
742
+ ) ;
743
+
744
+ // "dist" profile would normally set the channel to "auto-detect", but includes should
745
+ // override profile settings, so we expect this to be "dev" here.
746
+ assert_eq ! ( config. channel, "dev" ) ;
747
+ }
0 commit comments