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
4
use std:: path:: Path ;
5
+ use std:: { env, fs} ;
6
6
7
7
use build_helper:: ci:: CiEnv ;
8
8
use clap:: CommandFactory ;
@@ -23,6 +23,19 @@ 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 test_specific_dirname ( ) -> String {
34
+ let current = std:: thread:: current ( ) ;
35
+ // Replace "::" with "_" to make it safe for directory names on Windows systems
36
+ current. name ( ) . unwrap ( ) . replace ( "::" , "_" )
37
+ }
38
+
26
39
#[ test]
27
40
fn download_ci_llvm ( ) {
28
41
let config = parse ( "llvm.download-ci-llvm = false" ) ;
@@ -539,3 +552,210 @@ fn test_ci_flag() {
539
552
let config = Config :: parse_inner ( Flags :: parse ( & [ "check" . into ( ) ] ) , |& _| toml:: from_str ( "" ) ) ;
540
553
assert_eq ! ( config. is_running_on_ci, CiEnv :: is_ci( ) ) ;
541
554
}
555
+
556
+ #[ test]
557
+ fn test_precedence_of_includes ( ) {
558
+ let testdir = parse ( "" ) . tempdir ( ) . join ( test_specific_dirname ( ) ) ;
559
+
560
+ // clean up any old test files
561
+ let _ = fs:: remove_dir_all ( & testdir) ;
562
+ let _ = fs:: create_dir_all ( & testdir) ;
563
+
564
+ let root_config = testdir. join ( "config.toml" ) ;
565
+ let root_config_content = br#"
566
+ include = ["./extension.toml"]
567
+
568
+ [llvm]
569
+ link-jobs = 2
570
+ "# ;
571
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content) . unwrap ( ) ;
572
+
573
+ let extension = testdir. join ( "extension.toml" ) ;
574
+ let extension_content = br#"
575
+ change-id=543
576
+ include = ["./extension2.toml"]
577
+ "# ;
578
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
579
+
580
+ let extension = testdir. join ( "extension2.toml" ) ;
581
+ let extension_content = br#"
582
+ change-id=742
583
+
584
+ [llvm]
585
+ link-jobs = 10
586
+
587
+ [build]
588
+ description = "Some creative description"
589
+ "# ;
590
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
591
+
592
+ let config = Config :: parse_inner (
593
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
594
+ get_toml,
595
+ ) ;
596
+
597
+ assert_eq ! ( config. change_id. unwrap( ) , ChangeId :: Id ( 543 ) ) ;
598
+ assert_eq ! ( config. llvm_link_jobs. unwrap( ) , 2 ) ;
599
+ assert_eq ! ( config. description. unwrap( ) , "Some creative description" ) ;
600
+ }
601
+
602
+ #[ test]
603
+ #[ should_panic( expected = "Cyclic inclusion detected" ) ]
604
+ fn test_cyclic_include_direct ( ) {
605
+ let testdir = parse ( "" ) . tempdir ( ) . join ( test_specific_dirname ( ) ) ;
606
+
607
+ // clean up any old test files
608
+ let _ = fs:: remove_dir_all ( & testdir) ;
609
+ let _ = fs:: create_dir_all ( & testdir) ;
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 = parse ( "" ) . tempdir ( ) . join ( test_specific_dirname ( ) ) ;
633
+
634
+ // clean up any old test files
635
+ let _ = fs:: remove_dir_all ( & testdir) ;
636
+ let _ = fs:: create_dir_all ( & testdir) ;
637
+
638
+ let root_config = testdir. join ( "config.toml" ) ;
639
+ let root_config_content = br#"
640
+ include = ["./extension.toml"]
641
+ "# ;
642
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content) . unwrap ( ) ;
643
+
644
+ let extension = testdir. join ( "extension.toml" ) ;
645
+ let extension_content = br#"
646
+ include = ["./extension2.toml"]
647
+ "# ;
648
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
649
+
650
+ let extension = testdir. join ( "extension2.toml" ) ;
651
+ let extension_content = br#"
652
+ include = ["./extension3.toml"]
653
+ "# ;
654
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
655
+
656
+ let extension = testdir. join ( "extension3.toml" ) ;
657
+ let extension_content = br#"
658
+ include = ["./extension.toml"]
659
+ "# ;
660
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
661
+
662
+ let config = Config :: parse_inner (
663
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
664
+ get_toml,
665
+ ) ;
666
+ }
667
+
668
+ #[ test]
669
+ fn test_include_absolute_paths ( ) {
670
+ let testdir = parse ( "" ) . tempdir ( ) . join ( test_specific_dirname ( ) ) ;
671
+
672
+ // clean up any old test files
673
+ let _ = fs:: remove_dir_all ( & testdir) ;
674
+ let _ = fs:: create_dir_all ( & testdir) ;
675
+
676
+ let extension = testdir. join ( "extension.toml" ) ;
677
+ File :: create ( & extension) . unwrap ( ) . write_all ( & [ ] ) . unwrap ( ) ;
678
+
679
+ let root_config = testdir. join ( "config.toml" ) ;
680
+ let root_config_content =
681
+ format ! ( "include = [\" {}\" ]" , extension. canonicalize( ) . unwrap( ) . to_str( ) . unwrap( ) ) ;
682
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content. as_bytes ( ) ) . unwrap ( ) ;
683
+
684
+ let config = Config :: parse_inner (
685
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
686
+ get_toml,
687
+ ) ;
688
+ }
689
+
690
+ #[ test]
691
+ fn test_include_relative_paths ( ) {
692
+ let testdir = parse ( "" ) . tempdir ( ) . join ( test_specific_dirname ( ) ) ;
693
+
694
+ // clean up any old test files
695
+ let _ = fs:: remove_dir_all ( & testdir) ;
696
+ let _ = fs:: create_dir_all ( & testdir. join ( "subdir/another_subdir" ) ) ;
697
+
698
+ let root_config = testdir. join ( "config.toml" ) ;
699
+ let root_config_content = br#"
700
+ include = ["./subdir/extension.toml"]
701
+ "# ;
702
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content) . unwrap ( ) ;
703
+
704
+ let extension = testdir. join ( "subdir/extension.toml" ) ;
705
+ let extension_content = br#"
706
+ include = ["../extension2.toml"]
707
+ "# ;
708
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
709
+
710
+ let extension = testdir. join ( "extension2.toml" ) ;
711
+ let extension_content = br#"
712
+ include = ["./subdir/another_subdir/extension3.toml"]
713
+ "# ;
714
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
715
+
716
+ let extension = testdir. join ( "subdir/another_subdir/extension3.toml" ) ;
717
+ let extension_content = br#"
718
+ include = ["../../extension4.toml"]
719
+ "# ;
720
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
721
+
722
+ let extension = testdir. join ( "extension4.toml" ) ;
723
+ File :: create ( extension) . unwrap ( ) . write_all ( & [ ] ) . unwrap ( ) ;
724
+
725
+ let config = Config :: parse_inner (
726
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
727
+ get_toml,
728
+ ) ;
729
+ }
730
+
731
+ #[ test]
732
+ fn test_include_precedence_over_profile ( ) {
733
+ let testdir = parse ( "" ) . tempdir ( ) . join ( test_specific_dirname ( ) ) ;
734
+
735
+ // clean up any old test files
736
+ let _ = fs:: remove_dir_all ( & testdir) ;
737
+ let _ = fs:: create_dir_all ( & testdir) ;
738
+
739
+ let root_config = testdir. join ( "config.toml" ) ;
740
+ let root_config_content = br#"
741
+ profile = "dist"
742
+ include = ["./extension.toml"]
743
+ "# ;
744
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content) . unwrap ( ) ;
745
+
746
+ let extension = testdir. join ( "extension.toml" ) ;
747
+ let extension_content = br#"
748
+ [rust]
749
+ channel = "dev"
750
+ "# ;
751
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
752
+
753
+ let config = Config :: parse_inner (
754
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
755
+ get_toml,
756
+ ) ;
757
+
758
+ // "dist" profile would normally set the channel to "auto-detect", but includes should
759
+ // override profile settings, so we expect this to be "dev" here.
760
+ assert_eq ! ( config. channel, "dev" ) ;
761
+ }
0 commit comments