@@ -4,6 +4,7 @@ use anyhow::{Context, Error};
4
4
use build_helper:: stage0_parser:: { Stage0Config , VersionMetadata , parse_stage0_file} ;
5
5
use curl:: easy:: Easy ;
6
6
use indexmap:: IndexMap ;
7
+ use sha2:: { Digest , Sha256 } ;
7
8
8
9
const PATH : & str = "src/stage0" ;
9
10
const COMPILER_COMPONENTS : & [ & str ] = & [ "rustc" , "rust-std" , "cargo" , "clippy-preview" ] ;
@@ -13,13 +14,14 @@ struct Tool {
13
14
config : Stage0Config ,
14
15
15
16
channel : Channel ,
16
- date : Option < String > ,
17
+ compiler_date : Option < String > ,
18
+ rustfmt_date : Option < String > ,
17
19
version : [ u16 ; 3 ] ,
18
20
checksums : IndexMap < String , String > ,
19
21
}
20
22
21
23
impl Tool {
22
- fn new ( date : Option < String > ) -> Result < Self , Error > {
24
+ fn new ( compiler_date : Option < String > , rustfmt_date : Option < String > ) -> Result < Self , Error > {
23
25
let channel = match std:: fs:: read_to_string ( "src/ci/channel" ) ?. trim ( ) {
24
26
"stable" => Channel :: Stable ,
25
27
"beta" => Channel :: Beta ,
@@ -38,7 +40,14 @@ impl Tool {
38
40
39
41
let existing = parse_stage0_file ( ) ;
40
42
41
- Ok ( Self { channel, version, date, config : existing. config , checksums : IndexMap :: new ( ) } )
43
+ Ok ( Self {
44
+ channel,
45
+ version,
46
+ compiler_date,
47
+ rustfmt_date,
48
+ config : existing. config ,
49
+ checksums : IndexMap :: new ( ) ,
50
+ } )
42
51
}
43
52
44
53
fn update_stage0_file ( mut self ) -> Result < ( ) , Error > {
@@ -78,10 +87,21 @@ impl Tool {
78
87
file_content. push_str ( "\n " ) ;
79
88
80
89
let compiler = self . detect_compiler ( ) ?;
90
+ file_content. push_str ( & format ! (
91
+ "compiler_channel_manifest_hash={}\n " ,
92
+ compiler. channel_manifest_hash
93
+ ) ) ;
94
+ file_content. push_str ( & format ! ( "compiler_git_commit_hash={}\n " , compiler. git_commit_hash) ) ;
81
95
file_content. push_str ( & format ! ( "compiler_date={}\n " , compiler. date) ) ;
82
96
file_content. push_str ( & format ! ( "compiler_version={}\n " , compiler. version) ) ;
83
97
84
98
if let Some ( rustfmt) = self . detect_rustfmt ( ) ? {
99
+ file_content. push_str ( & format ! (
100
+ "rustfmt_channel_manifest_hash={}\n " ,
101
+ rustfmt. channel_manifest_hash
102
+ ) ) ;
103
+ file_content
104
+ . push_str ( & format ! ( "rustfmt_git_commit_hash={}\n " , rustfmt. git_commit_hash) ) ;
85
105
file_content. push_str ( & format ! ( "rustfmt_date={}\n " , rustfmt. date) ) ;
86
106
file_content. push_str ( & format ! ( "rustfmt_version={}\n " , rustfmt. version) ) ;
87
107
}
@@ -112,9 +132,16 @@ impl Tool {
112
132
Channel :: Nightly => "beta" . to_string ( ) ,
113
133
} ;
114
134
115
- let manifest = fetch_manifest ( & self . config , & channel, self . date . as_deref ( ) ) ?;
135
+ let ( manifest, manifest_hash) =
136
+ fetch_manifest ( & self . config , & channel, self . compiler_date . as_deref ( ) ) ?;
116
137
self . collect_checksums ( & manifest, COMPILER_COMPONENTS ) ?;
117
138
Ok ( VersionMetadata {
139
+ channel_manifest_hash : manifest_hash,
140
+ git_commit_hash : manifest. pkg [ "rust" ]
141
+ . git_commit_hash
142
+ . as_ref ( )
143
+ . expect ( "invalid git_commit_hash" )
144
+ . into ( ) ,
118
145
date : manifest. date ,
119
146
version : if self . channel == Channel :: Nightly {
120
147
"beta" . to_string ( )
@@ -138,9 +165,19 @@ impl Tool {
138
165
return Ok ( None ) ;
139
166
}
140
167
141
- let manifest = fetch_manifest ( & self . config , "nightly" , self . date . as_deref ( ) ) ?;
168
+ let ( manifest, manifest_hash) =
169
+ fetch_manifest ( & self . config , "nightly" , self . rustfmt_date . as_deref ( ) ) ?;
142
170
self . collect_checksums ( & manifest, RUSTFMT_COMPONENTS ) ?;
143
- Ok ( Some ( VersionMetadata { date : manifest. date , version : "nightly" . into ( ) } ) )
171
+ Ok ( Some ( VersionMetadata {
172
+ channel_manifest_hash : manifest_hash,
173
+ git_commit_hash : manifest. pkg [ "rust" ]
174
+ . git_commit_hash
175
+ . as_ref ( )
176
+ . expect ( "invalid git_commit_hash" )
177
+ . into ( ) ,
178
+ date : manifest. date ,
179
+ version : "nightly" . into ( ) ,
180
+ } ) )
144
181
}
145
182
146
183
fn collect_checksums ( & mut self , manifest : & Manifest , components : & [ & str ] ) -> Result < ( ) , Error > {
@@ -164,12 +201,29 @@ impl Tool {
164
201
}
165
202
}
166
203
}
204
+ for artifact in manifest. artifacts . values ( ) {
205
+ for targets in artifact. target . values ( ) {
206
+ for target in targets {
207
+ let url = target
208
+ . url
209
+ . strip_prefix ( & prefix)
210
+ . ok_or_else ( || {
211
+ anyhow:: anyhow!(
212
+ "url doesn't start with dist server base: {}" ,
213
+ target. url
214
+ )
215
+ } ) ?
216
+ . to_string ( ) ;
217
+ self . checksums . insert ( url, target. hash_sha256 . clone ( ) ) ;
218
+ }
219
+ }
220
+ }
167
221
Ok ( ( ) )
168
222
}
169
223
}
170
224
171
225
fn main ( ) -> Result < ( ) , Error > {
172
- let tool = Tool :: new ( std:: env:: args ( ) . nth ( 1 ) ) ?;
226
+ let tool = Tool :: new ( std:: env:: args ( ) . nth ( 1 ) , std :: env :: args ( ) . nth ( 2 ) ) ?;
173
227
tool. update_stage0_file ( ) ?;
174
228
Ok ( ( ) )
175
229
}
@@ -178,14 +232,21 @@ fn fetch_manifest(
178
232
config : & Stage0Config ,
179
233
channel : & str ,
180
234
date : Option < & str > ,
181
- ) -> Result < Manifest , Error > {
235
+ ) -> Result < ( Manifest , String ) , Error > {
182
236
let url = if let Some ( date) = date {
183
237
format ! ( "{}/dist/{}/channel-rust-{}.toml" , config. dist_server, date, channel)
184
238
} else {
185
239
format ! ( "{}/dist/channel-rust-{}.toml" , config. dist_server, channel)
186
240
} ;
187
241
188
- Ok ( toml:: from_slice ( & http_get ( & url) ?) ?)
242
+ let manifest_bytes = http_get ( & url) ?;
243
+ let manifest = toml:: from_slice ( & manifest_bytes) ?;
244
+
245
+ let mut sha256 = Sha256 :: new ( ) ;
246
+ sha256. update ( & manifest_bytes) ;
247
+ let manifest_hash = hex:: encode ( sha256. finalize ( ) ) ;
248
+
249
+ Ok ( ( manifest, manifest_hash) )
189
250
}
190
251
191
252
fn http_get ( url : & str ) -> Result < Vec < u8 > , Error > {
@@ -215,11 +276,14 @@ enum Channel {
215
276
struct Manifest {
216
277
date : String ,
217
278
pkg : IndexMap < String , ManifestPackage > ,
279
+ artifacts : IndexMap < String , ManifestArtifact > ,
218
280
}
219
281
220
282
#[ derive( Debug , serde:: Serialize , serde:: Deserialize ) ]
221
283
struct ManifestPackage {
222
284
version : String ,
285
+ #[ serde( default ) ]
286
+ git_commit_hash : Option < String > ,
223
287
target : IndexMap < String , ManifestTargetPackage > ,
224
288
}
225
289
@@ -230,3 +294,15 @@ struct ManifestTargetPackage {
230
294
xz_url : Option < String > ,
231
295
xz_hash : Option < String > ,
232
296
}
297
+
298
+ #[ derive( Debug , serde:: Serialize , serde:: Deserialize ) ]
299
+ struct ManifestArtifact {
300
+ target : IndexMap < String , Vec < ManifestTargetArtifact > > ,
301
+ }
302
+
303
+ #[ derive( Debug , serde:: Serialize , serde:: Deserialize ) ]
304
+ #[ serde( rename_all = "kebab-case" ) ]
305
+ struct ManifestTargetArtifact {
306
+ url : String ,
307
+ hash_sha256 : String ,
308
+ }
0 commit comments