@@ -4,6 +4,7 @@ use anyhow::{Context, Error};
44use build_helper:: stage0_parser:: { Stage0Config , VersionMetadata , parse_stage0_file} ;
55use curl:: easy:: Easy ;
66use indexmap:: IndexMap ;
7+ use sha2:: { Digest , Sha256 } ;
78
89const PATH : & str = "src/stage0" ;
910const COMPILER_COMPONENTS : & [ & str ] = & [ "rustc" , "rust-std" , "cargo" , "clippy-preview" ] ;
@@ -13,13 +14,14 @@ struct Tool {
1314 config : Stage0Config ,
1415
1516 channel : Channel ,
16- date : Option < String > ,
17+ compiler_date : Option < String > ,
18+ rustfmt_date : Option < String > ,
1719 version : [ u16 ; 3 ] ,
1820 checksums : IndexMap < String , String > ,
1921}
2022
2123impl Tool {
22- fn new ( date : Option < String > ) -> Result < Self , Error > {
24+ fn new ( compiler_date : Option < String > , rustfmt_date : Option < String > ) -> Result < Self , Error > {
2325 let channel = match std:: fs:: read_to_string ( "src/ci/channel" ) ?. trim ( ) {
2426 "stable" => Channel :: Stable ,
2527 "beta" => Channel :: Beta ,
@@ -38,7 +40,14 @@ impl Tool {
3840
3941 let existing = parse_stage0_file ( ) ;
4042
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+ } )
4251 }
4352
4453 fn update_stage0_file ( mut self ) -> Result < ( ) , Error > {
@@ -78,10 +87,21 @@ impl Tool {
7887 file_content. push_str ( "\n " ) ;
7988
8089 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) ) ;
8195 file_content. push_str ( & format ! ( "compiler_date={}\n " , compiler. date) ) ;
8296 file_content. push_str ( & format ! ( "compiler_version={}\n " , compiler. version) ) ;
8397
8498 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) ) ;
85105 file_content. push_str ( & format ! ( "rustfmt_date={}\n " , rustfmt. date) ) ;
86106 file_content. push_str ( & format ! ( "rustfmt_version={}\n " , rustfmt. version) ) ;
87107 }
@@ -112,9 +132,16 @@ impl Tool {
112132 Channel :: Nightly => "beta" . to_string ( ) ,
113133 } ;
114134
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 ( ) ) ?;
116137 self . collect_checksums ( & manifest, COMPILER_COMPONENTS ) ?;
117138 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 ( ) ,
118145 date : manifest. date ,
119146 version : if self . channel == Channel :: Nightly {
120147 "beta" . to_string ( )
@@ -138,9 +165,19 @@ impl Tool {
138165 return Ok ( None ) ;
139166 }
140167
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 ( ) ) ?;
142170 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+ } ) )
144181 }
145182
146183 fn collect_checksums ( & mut self , manifest : & Manifest , components : & [ & str ] ) -> Result < ( ) , Error > {
@@ -164,12 +201,29 @@ impl Tool {
164201 }
165202 }
166203 }
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+ }
167221 Ok ( ( ) )
168222 }
169223}
170224
171225fn 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 ) ) ?;
173227 tool. update_stage0_file ( ) ?;
174228 Ok ( ( ) )
175229}
@@ -178,14 +232,21 @@ fn fetch_manifest(
178232 config : & Stage0Config ,
179233 channel : & str ,
180234 date : Option < & str > ,
181- ) -> Result < Manifest , Error > {
235+ ) -> Result < ( Manifest , String ) , Error > {
182236 let url = if let Some ( date) = date {
183237 format ! ( "{}/dist/{}/channel-rust-{}.toml" , config. dist_server, date, channel)
184238 } else {
185239 format ! ( "{}/dist/channel-rust-{}.toml" , config. dist_server, channel)
186240 } ;
187241
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) )
189250}
190251
191252fn http_get ( url : & str ) -> Result < Vec < u8 > , Error > {
@@ -215,11 +276,14 @@ enum Channel {
215276struct Manifest {
216277 date : String ,
217278 pkg : IndexMap < String , ManifestPackage > ,
279+ artifacts : IndexMap < String , ManifestArtifact > ,
218280}
219281
220282#[ derive( Debug , serde:: Serialize , serde:: Deserialize ) ]
221283struct ManifestPackage {
222284 version : String ,
285+ #[ serde( default ) ]
286+ git_commit_hash : Option < String > ,
223287 target : IndexMap < String , ManifestTargetPackage > ,
224288}
225289
@@ -230,3 +294,15 @@ struct ManifestTargetPackage {
230294 xz_url : Option < String > ,
231295 xz_hash : Option < String > ,
232296}
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