@@ -33,24 +33,38 @@ impl OverrideFile {
33
33
#[ derive( Debug , Default , Deserialize , PartialEq , Eq ) ]
34
34
struct ToolchainSection {
35
35
channel : Option < String > ,
36
+ path : Option < PathBuf > ,
36
37
components : Option < Vec < String > > ,
37
38
targets : Option < Vec < String > > ,
38
39
profile : Option < String > ,
39
40
}
40
41
41
42
impl ToolchainSection {
42
43
fn is_empty ( & self ) -> bool {
43
- self . channel . is_none ( ) && self . components . is_none ( ) && self . targets . is_none ( )
44
+ self . channel . is_none ( )
45
+ && self . components . is_none ( )
46
+ && self . targets . is_none ( )
47
+ && self . path . is_none ( )
44
48
}
45
49
}
46
50
47
51
impl < T : Into < String > > From < T > for OverrideFile {
48
52
fn from ( channel : T ) -> Self {
49
- Self {
50
- toolchain : ToolchainSection {
51
- channel : Some ( channel. into ( ) ) ,
52
- ..Default :: default ( )
53
- } ,
53
+ let override_ = channel. into ( ) ;
54
+ if Path :: new ( & override_) . is_absolute ( ) {
55
+ Self {
56
+ toolchain : ToolchainSection {
57
+ path : Some ( PathBuf :: from ( override_) ) ,
58
+ ..Default :: default ( )
59
+ } ,
60
+ }
61
+ } else {
62
+ Self {
63
+ toolchain : ToolchainSection {
64
+ channel : Some ( override_) ,
65
+ ..Default :: default ( )
66
+ } ,
67
+ }
54
68
}
55
69
}
56
70
}
@@ -74,7 +88,7 @@ impl Display for OverrideReason {
74
88
}
75
89
}
76
90
77
- #[ derive( Default ) ]
91
+ #[ derive( Default , Debug ) ]
78
92
struct OverrideCfg < ' a > {
79
93
toolchain : Option < Toolchain < ' a > > ,
80
94
components : Vec < String > ,
@@ -83,11 +97,27 @@ struct OverrideCfg<'a> {
83
97
}
84
98
85
99
impl < ' a > OverrideCfg < ' a > {
86
- fn from_file ( cfg : & ' a Cfg , file : OverrideFile ) -> Result < Self > {
100
+ fn from_file (
101
+ cfg : & ' a Cfg ,
102
+ cfg_path : Option < impl AsRef < Path > > ,
103
+ file : OverrideFile ,
104
+ ) -> Result < Self > {
87
105
Ok ( Self {
88
- toolchain : match file. toolchain . channel {
89
- Some ( name) => Some ( Toolchain :: from ( cfg, & name) ?) ,
90
- None => None ,
106
+ toolchain : match ( file. toolchain . channel , file. toolchain . path ) {
107
+ ( Some ( name) , None ) => Some ( Toolchain :: from ( cfg, & name) ?) ,
108
+ ( None , Some ( path) ) => {
109
+ if file. toolchain . targets . is_some ( )
110
+ || file. toolchain . components . is_some ( )
111
+ || file. toolchain . profile . is_some ( )
112
+ {
113
+ return Err ( ErrorKind :: CannotSpecifyPathAndOptions ( path. into ( ) ) . into ( ) ) ;
114
+ }
115
+ Some ( Toolchain :: from_path ( cfg, cfg_path, & path) ?)
116
+ }
117
+ ( Some ( channel) , Some ( path) ) => {
118
+ return Err ( ErrorKind :: CannotSpecifyChannelAndPath ( channel, path. into ( ) ) . into ( ) )
119
+ }
120
+ ( None , None ) => None ,
91
121
} ,
92
122
components : file. toolchain . components . unwrap_or_default ( ) ,
93
123
targets : file. toolchain . targets . unwrap_or_default ( ) ,
@@ -522,15 +552,21 @@ impl Cfg {
522
552
}
523
553
OverrideReason :: OverrideDB ( ref path) => format ! (
524
554
"the directory override for '{}' specifies an uninstalled toolchain" ,
525
- path. display( )
555
+ utils :: canonicalize_path ( path, self . notify_handler . as_ref ( ) ) . display( ) ,
526
556
) ,
527
557
OverrideReason :: ToolchainFile ( ref path) => format ! (
528
558
"the toolchain file at '{}' specifies an uninstalled toolchain" ,
529
- path. display( )
559
+ utils :: canonicalize_path ( path, self . notify_handler . as_ref ( ) ) . display( ) ,
530
560
) ,
531
561
} ;
532
562
533
- let override_cfg = OverrideCfg :: from_file ( self , file) ?;
563
+ let cfg_file = if let OverrideReason :: ToolchainFile ( ref path) = reason {
564
+ Some ( path)
565
+ } else {
566
+ None
567
+ } ;
568
+
569
+ let override_cfg = OverrideCfg :: from_file ( self , cfg_file, file) ?;
534
570
if let Some ( toolchain) = & override_cfg. toolchain {
535
571
// Overridden toolchains can be literally any string, but only
536
572
// distributable toolchains will be auto-installed by the wrapping
@@ -557,8 +593,7 @@ impl Cfg {
557
593
settings : & Settings ,
558
594
) -> Result < Option < ( OverrideFile , OverrideReason ) > > {
559
595
let notify = self . notify_handler . as_ref ( ) ;
560
- let dir = utils:: canonicalize_path ( dir, notify) ;
561
- let mut dir = Some ( & * dir) ;
596
+ let mut dir = Some ( dir) ;
562
597
563
598
while let Some ( d) = dir {
564
599
// First check the override database
@@ -955,6 +990,7 @@ mod tests {
955
990
OverrideFile {
956
991
toolchain: ToolchainSection {
957
992
channel: Some ( contents. into( ) ) ,
993
+ path: None ,
958
994
components: None ,
959
995
targets: None ,
960
996
profile: None ,
@@ -978,6 +1014,7 @@ profile = "default"
978
1014
OverrideFile {
979
1015
toolchain: ToolchainSection {
980
1016
channel: Some ( "nightly-2020-07-10" . into( ) ) ,
1017
+ path: None ,
981
1018
components: Some ( vec![ "rustfmt" . into( ) , "rustc-dev" . into( ) ] ) ,
982
1019
targets: Some ( vec![
983
1020
"wasm32-unknown-unknown" . into( ) ,
@@ -1001,6 +1038,28 @@ channel = "nightly-2020-07-10"
1001
1038
OverrideFile {
1002
1039
toolchain: ToolchainSection {
1003
1040
channel: Some ( "nightly-2020-07-10" . into( ) ) ,
1041
+ path: None ,
1042
+ components: None ,
1043
+ targets: None ,
1044
+ profile: None ,
1045
+ }
1046
+ }
1047
+ ) ;
1048
+ }
1049
+
1050
+ #[ test]
1051
+ fn parse_toml_toolchain_file_only_path ( ) {
1052
+ let contents = r#"[toolchain]
1053
+ path = "foobar"
1054
+ "# ;
1055
+
1056
+ let result = Cfg :: parse_override_file ( contents, ParseMode :: Both ) ;
1057
+ assert_eq ! (
1058
+ result. unwrap( ) ,
1059
+ OverrideFile {
1060
+ toolchain: ToolchainSection {
1061
+ channel: None ,
1062
+ path: Some ( "foobar" . into( ) ) ,
1004
1063
components: None ,
1005
1064
targets: None ,
1006
1065
profile: None ,
@@ -1022,6 +1081,7 @@ components = []
1022
1081
OverrideFile {
1023
1082
toolchain: ToolchainSection {
1024
1083
channel: Some ( "nightly-2020-07-10" . into( ) ) ,
1084
+ path: None ,
1025
1085
components: Some ( vec![ ] ) ,
1026
1086
targets: None ,
1027
1087
profile: None ,
@@ -1043,6 +1103,7 @@ targets = []
1043
1103
OverrideFile {
1044
1104
toolchain: ToolchainSection {
1045
1105
channel: Some ( "nightly-2020-07-10" . into( ) ) ,
1106
+ path: None ,
1046
1107
components: None ,
1047
1108
targets: Some ( vec![ ] ) ,
1048
1109
profile: None ,
@@ -1063,6 +1124,7 @@ components = [ "rustfmt" ]
1063
1124
OverrideFile {
1064
1125
toolchain: ToolchainSection {
1065
1126
channel: None ,
1127
+ path: None ,
1066
1128
components: Some ( vec![ "rustfmt" . into( ) ] ) ,
1067
1129
targets: None ,
1068
1130
profile: None ,
0 commit comments