@@ -18,6 +18,7 @@ use anyhow::{anyhow, bail, Error};
18
18
use docsrs_metadata:: { Metadata , DEFAULT_TARGETS , HOST_TARGET } ;
19
19
use failure:: Error as FailureError ;
20
20
use postgres:: Client ;
21
+ use regex:: Regex ;
21
22
use rustwide:: cmd:: { Command , CommandError , SandboxBuilder , SandboxImage } ;
22
23
use rustwide:: logging:: { self , LogStorage } ;
23
24
use rustwide:: toolchain:: ToolchainError ;
@@ -73,7 +74,16 @@ impl RustwideBuilder {
73
74
. purge_all_build_dirs ( )
74
75
. map_err ( FailureError :: compat) ?;
75
76
76
- let toolchain = Toolchain :: dist ( & config. toolchain ) ;
77
+ // If the toolchain is all hex, assume it references an artifact from
78
+ // CI, for instance an `@bors try` build.
79
+ let re = Regex :: new ( r"^[a-fA-F0-9]+$" ) . unwrap ( ) ;
80
+ let toolchain = if re. is_match ( & config. toolchain ) {
81
+ debug ! ( "using CI build {}" , & config. toolchain) ;
82
+ Toolchain :: ci ( & config. toolchain , false )
83
+ } else {
84
+ debug ! ( "using toolchain {}" , & config. toolchain) ;
85
+ Toolchain :: dist ( & config. toolchain )
86
+ } ;
77
87
78
88
Ok ( RustwideBuilder {
79
89
workspace,
@@ -108,6 +118,23 @@ impl RustwideBuilder {
108
118
}
109
119
110
120
pub fn update_toolchain ( & mut self ) -> Result < bool > {
121
+ // For CI builds, a lot of the normal update_toolchain things don't apply.
122
+ // CI builds are only for one platform (https://forge.rust-lang.org/infra/docs/rustc-ci.html#try-builds)
123
+ // so we only try installing for the current platform. If that's not a match,
124
+ // for instance if we're running on macOS or Windows, this will error.
125
+ // Also, detecting the rustc version relies on calling rustc through rustup with the
126
+ // +channel argument, but the +channel argument doesn't work for CI builds. So
127
+ // we fake the rustc version and install from scratch every time since we can't detect
128
+ // the already-installed rustc version.
129
+ if let Some ( ci) = self . toolchain . as_ci ( ) {
130
+ self . toolchain
131
+ . install ( & self . workspace )
132
+ . map_err ( FailureError :: compat) ?;
133
+ self . rustc_version = format ! ( "rustc 1.9999.0-nightly ({} 2999-12-29)" , ci. sha( ) ) ;
134
+ self . add_essential_files ( ) ?;
135
+ return Ok ( true ) ;
136
+ }
137
+
111
138
// Ignore errors if detection fails.
112
139
let old_version = self . detect_rustc_version ( ) . ok ( ) ;
113
140
@@ -174,6 +201,8 @@ impl RustwideBuilder {
174
201
Ok ( has_changed)
175
202
}
176
203
204
+ /// Return a string containing the output of `rustc --version`. Only valid
205
+ /// for dist toolchains. Will error if run with a CI toolchain.
177
206
fn detect_rustc_version ( & self ) -> Result < String > {
178
207
info ! ( "detecting rustc's version..." ) ;
179
208
let res = Command :: new ( & self . workspace , self . toolchain . rustc ( ) )
@@ -190,7 +219,6 @@ impl RustwideBuilder {
190
219
}
191
220
192
221
pub fn add_essential_files ( & mut self ) -> Result < ( ) > {
193
- self . rustc_version = self . detect_rustc_version ( ) ?;
194
222
let rustc_version = parse_rustc_version ( & self . rustc_version ) ?;
195
223
196
224
info ! ( "building a dummy crate to get essential files" ) ;
0 commit comments