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,189 @@ 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 extension_absolute_path =
673
+ extension. canonicalize ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . replace ( '\\' , r"\\" ) ;
674
+ let root_config_content = format ! ( r#"include = ["{}"]"# , extension_absolute_path) ;
675
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content. as_bytes ( ) ) . unwrap ( ) ;
676
+
677
+ let config = Config :: parse_inner (
678
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
679
+ get_toml,
680
+ ) ;
681
+ }
682
+
683
+ #[ test]
684
+ fn test_include_relative_paths ( ) {
685
+ let testdir = prepare_test_specific_dir ( ) ;
686
+
687
+ let _ = fs:: create_dir_all ( & testdir. join ( "subdir/another_subdir" ) ) ;
688
+
689
+ let root_config = testdir. join ( "config.toml" ) ;
690
+ let root_config_content = br#"
691
+ include = ["./subdir/extension.toml"]
692
+ "# ;
693
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content) . unwrap ( ) ;
694
+
695
+ let extension = testdir. join ( "subdir/extension.toml" ) ;
696
+ let extension_content = br#"
697
+ include = ["../extension2.toml"]
698
+ "# ;
699
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
700
+
701
+ let extension = testdir. join ( "extension2.toml" ) ;
702
+ let extension_content = br#"
703
+ include = ["./subdir/another_subdir/extension3.toml"]
704
+ "# ;
705
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
706
+
707
+ let extension = testdir. join ( "subdir/another_subdir/extension3.toml" ) ;
708
+ let extension_content = br#"
709
+ include = ["../../extension4.toml"]
710
+ "# ;
711
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
712
+
713
+ let extension = testdir. join ( "extension4.toml" ) ;
714
+ File :: create ( extension) . unwrap ( ) . write_all ( & [ ] ) . unwrap ( ) ;
715
+
716
+ let config = Config :: parse_inner (
717
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
718
+ get_toml,
719
+ ) ;
720
+ }
721
+
722
+ #[ test]
723
+ fn test_include_precedence_over_profile ( ) {
724
+ let testdir = prepare_test_specific_dir ( ) ;
725
+
726
+ let root_config = testdir. join ( "config.toml" ) ;
727
+ let root_config_content = br#"
728
+ profile = "dist"
729
+ include = ["./extension.toml"]
730
+ "# ;
731
+ File :: create ( & root_config) . unwrap ( ) . write_all ( root_config_content) . unwrap ( ) ;
732
+
733
+ let extension = testdir. join ( "extension.toml" ) ;
734
+ let extension_content = br#"
735
+ [rust]
736
+ channel = "dev"
737
+ "# ;
738
+ File :: create ( extension) . unwrap ( ) . write_all ( extension_content) . unwrap ( ) ;
739
+
740
+ let config = Config :: parse_inner (
741
+ Flags :: parse ( & [ "check" . to_owned ( ) , format ! ( "--config={}" , root_config. to_str( ) . unwrap( ) ) ] ) ,
742
+ get_toml,
743
+ ) ;
744
+
745
+ // "dist" profile would normally set the channel to "auto-detect", but includes should
746
+ // override profile settings, so we expect this to be "dev" here.
747
+ assert_eq ! ( config. channel, "dev" ) ;
748
+ }
0 commit comments