]>
Commit | Line | Data |
---|---|---|
9fa01778 XL |
1 | #![deny(rust_2018_idioms)] |
2 | ||
3 | use toml; | |
4 | use serde::Serialize; | |
32a655c1 | 5 | |
cc61c64b | 6 | use std::collections::BTreeMap; |
32a655c1 | 7 | use std::env; |
0731742a | 8 | use std::fs; |
32a655c1 SL |
9 | use std::io::{self, Read, Write}; |
10 | use std::path::{PathBuf, Path}; | |
11 | use std::process::{Command, Stdio}; | |
12 | ||
13 | static HOSTS: &'static [&'static str] = &[ | |
14 | "aarch64-unknown-linux-gnu", | |
15 | "arm-unknown-linux-gnueabi", | |
16 | "arm-unknown-linux-gnueabihf", | |
17 | "armv7-unknown-linux-gnueabihf", | |
18 | "i686-apple-darwin", | |
19 | "i686-pc-windows-gnu", | |
20 | "i686-pc-windows-msvc", | |
21 | "i686-unknown-linux-gnu", | |
22 | "mips-unknown-linux-gnu", | |
23 | "mips64-unknown-linux-gnuabi64", | |
24 | "mips64el-unknown-linux-gnuabi64", | |
25 | "mipsel-unknown-linux-gnu", | |
26 | "powerpc-unknown-linux-gnu", | |
27 | "powerpc64-unknown-linux-gnu", | |
28 | "powerpc64le-unknown-linux-gnu", | |
29 | "s390x-unknown-linux-gnu", | |
30 | "x86_64-apple-darwin", | |
31 | "x86_64-pc-windows-gnu", | |
32 | "x86_64-pc-windows-msvc", | |
33 | "x86_64-unknown-freebsd", | |
34 | "x86_64-unknown-linux-gnu", | |
35 | "x86_64-unknown-netbsd", | |
36 | ]; | |
37 | ||
38 | static TARGETS: &'static [&'static str] = &[ | |
39 | "aarch64-apple-ios", | |
8faf50e0 | 40 | "aarch64-fuchsia", |
32a655c1 | 41 | "aarch64-linux-android", |
a1dfa0c6 | 42 | "aarch64-pc-windows-msvc", |
ff7c6d11 | 43 | "aarch64-unknown-cloudabi", |
32a655c1 | 44 | "aarch64-unknown-linux-gnu", |
ea8adc8c | 45 | "aarch64-unknown-linux-musl", |
32a655c1 SL |
46 | "arm-linux-androideabi", |
47 | "arm-unknown-linux-gnueabi", | |
48 | "arm-unknown-linux-gnueabihf", | |
49 | "arm-unknown-linux-musleabi", | |
50 | "arm-unknown-linux-musleabihf", | |
ff7c6d11 | 51 | "armv5te-unknown-linux-gnueabi", |
83c7162d | 52 | "armv5te-unknown-linux-musleabi", |
32a655c1 SL |
53 | "armv7-apple-ios", |
54 | "armv7-linux-androideabi", | |
0731742a | 55 | "thumbv7neon-linux-androideabi", |
32a655c1 | 56 | "armv7-unknown-linux-gnueabihf", |
0731742a | 57 | "thumbv7neon-unknown-linux-gnueabihf", |
32a655c1 | 58 | "armv7-unknown-linux-musleabihf", |
b7449926 | 59 | "armebv7r-none-eabi", |
94b46f34 | 60 | "armebv7r-none-eabihf", |
b7449926 XL |
61 | "armv7r-none-eabi", |
62 | "armv7r-none-eabihf", | |
32a655c1 SL |
63 | "armv7s-apple-ios", |
64 | "asmjs-unknown-emscripten", | |
65 | "i386-apple-ios", | |
66 | "i586-pc-windows-msvc", | |
67 | "i586-unknown-linux-gnu", | |
2c00a5a8 | 68 | "i586-unknown-linux-musl", |
32a655c1 SL |
69 | "i686-apple-darwin", |
70 | "i686-linux-android", | |
71 | "i686-pc-windows-gnu", | |
72 | "i686-pc-windows-msvc", | |
73 | "i686-unknown-freebsd", | |
74 | "i686-unknown-linux-gnu", | |
75 | "i686-unknown-linux-musl", | |
76 | "mips-unknown-linux-gnu", | |
77 | "mips-unknown-linux-musl", | |
78 | "mips64-unknown-linux-gnuabi64", | |
79 | "mips64el-unknown-linux-gnuabi64", | |
80 | "mipsel-unknown-linux-gnu", | |
81 | "mipsel-unknown-linux-musl", | |
9fa01778 | 82 | "nvptx64-nvidia-cuda", |
32a655c1 SL |
83 | "powerpc-unknown-linux-gnu", |
84 | "powerpc64-unknown-linux-gnu", | |
85 | "powerpc64le-unknown-linux-gnu", | |
b7449926 XL |
86 | "riscv32imc-unknown-none-elf", |
87 | "riscv32imac-unknown-none-elf", | |
9fa01778 XL |
88 | "riscv64imac-unknown-none-elf", |
89 | "riscv64gc-unknown-none-elf", | |
32a655c1 | 90 | "s390x-unknown-linux-gnu", |
8bb4bdeb | 91 | "sparc64-unknown-linux-gnu", |
ea8adc8c | 92 | "sparcv9-sun-solaris", |
83c7162d XL |
93 | "thumbv6m-none-eabi", |
94 | "thumbv7em-none-eabi", | |
95 | "thumbv7em-none-eabihf", | |
96 | "thumbv7m-none-eabi", | |
0731742a | 97 | "thumbv8m.main-none-eabi", |
32a655c1 | 98 | "wasm32-unknown-emscripten", |
ff7c6d11 | 99 | "wasm32-unknown-unknown", |
32a655c1 SL |
100 | "x86_64-apple-darwin", |
101 | "x86_64-apple-ios", | |
0731742a | 102 | "x86_64-fortanix-unknown-sgx", |
8faf50e0 | 103 | "x86_64-fuchsia", |
ff7c6d11 | 104 | "x86_64-linux-android", |
32a655c1 SL |
105 | "x86_64-pc-windows-gnu", |
106 | "x86_64-pc-windows-msvc", | |
107 | "x86_64-rumprun-netbsd", | |
ea8adc8c | 108 | "x86_64-sun-solaris", |
ff7c6d11 | 109 | "x86_64-unknown-cloudabi", |
32a655c1 SL |
110 | "x86_64-unknown-freebsd", |
111 | "x86_64-unknown-linux-gnu", | |
abe05a73 | 112 | "x86_64-unknown-linux-gnux32", |
32a655c1 SL |
113 | "x86_64-unknown-linux-musl", |
114 | "x86_64-unknown-netbsd", | |
3b2f2976 | 115 | "x86_64-unknown-redox", |
32a655c1 SL |
116 | ]; |
117 | ||
b7449926 XL |
118 | static DOCS_TARGETS: &'static [&'static str] = &[ |
119 | "i686-apple-darwin", | |
120 | "i686-pc-windows-gnu", | |
121 | "i686-pc-windows-msvc", | |
122 | "i686-unknown-linux-gnu", | |
123 | "x86_64-apple-darwin", | |
124 | "x86_64-pc-windows-gnu", | |
125 | "x86_64-pc-windows-msvc", | |
126 | "x86_64-unknown-linux-gnu", | |
127 | ]; | |
128 | ||
32a655c1 SL |
129 | static MINGW: &'static [&'static str] = &[ |
130 | "i686-pc-windows-gnu", | |
131 | "x86_64-pc-windows-gnu", | |
132 | ]; | |
133 | ||
3b2f2976 XL |
134 | #[derive(Serialize)] |
135 | #[serde(rename_all = "kebab-case")] | |
32a655c1 SL |
136 | struct Manifest { |
137 | manifest_version: String, | |
138 | date: String, | |
cc61c64b | 139 | pkg: BTreeMap<String, Package>, |
0731742a XL |
140 | renames: BTreeMap<String, Rename>, |
141 | profiles: BTreeMap<String, Vec<String>>, | |
32a655c1 SL |
142 | } |
143 | ||
3b2f2976 | 144 | #[derive(Serialize)] |
32a655c1 SL |
145 | struct Package { |
146 | version: String, | |
ea8adc8c | 147 | git_commit_hash: Option<String>, |
cc61c64b | 148 | target: BTreeMap<String, Target>, |
32a655c1 SL |
149 | } |
150 | ||
ea8adc8c XL |
151 | #[derive(Serialize)] |
152 | struct Rename { | |
153 | to: String, | |
154 | } | |
155 | ||
3b2f2976 | 156 | #[derive(Serialize)] |
32a655c1 SL |
157 | struct Target { |
158 | available: bool, | |
159 | url: Option<String>, | |
160 | hash: Option<String>, | |
7cac9316 XL |
161 | xz_url: Option<String>, |
162 | xz_hash: Option<String>, | |
32a655c1 SL |
163 | components: Option<Vec<Component>>, |
164 | extensions: Option<Vec<Component>>, | |
165 | } | |
166 | ||
7cac9316 XL |
167 | impl Target { |
168 | fn unavailable() -> Target { | |
169 | Target { | |
170 | available: false, | |
171 | url: None, | |
172 | hash: None, | |
173 | xz_url: None, | |
174 | xz_hash: None, | |
175 | components: None, | |
176 | extensions: None, | |
177 | } | |
178 | } | |
179 | } | |
180 | ||
3b2f2976 | 181 | #[derive(Serialize)] |
32a655c1 SL |
182 | struct Component { |
183 | pkg: String, | |
184 | target: String, | |
185 | } | |
186 | ||
187 | macro_rules! t { | |
188 | ($e:expr) => (match $e { | |
189 | Ok(e) => e, | |
190 | Err(e) => panic!("{} failed with {}", stringify!($e), e), | |
191 | }) | |
192 | } | |
193 | ||
194 | struct Builder { | |
8bb4bdeb XL |
195 | rust_release: String, |
196 | cargo_release: String, | |
3b2f2976 | 197 | rls_release: String, |
8faf50e0 | 198 | clippy_release: String, |
abe05a73 | 199 | rustfmt_release: String, |
8faf50e0 | 200 | llvm_tools_release: String, |
b7449926 | 201 | lldb_release: String, |
0731742a | 202 | miri_release: String, |
abe05a73 | 203 | |
32a655c1 SL |
204 | input: PathBuf, |
205 | output: PathBuf, | |
206 | gpg_passphrase: String, | |
cc61c64b | 207 | digests: BTreeMap<String, String>, |
32a655c1 SL |
208 | s3_address: String, |
209 | date: String, | |
abe05a73 XL |
210 | |
211 | rust_version: Option<String>, | |
212 | cargo_version: Option<String>, | |
213 | rls_version: Option<String>, | |
8faf50e0 | 214 | clippy_version: Option<String>, |
abe05a73 | 215 | rustfmt_version: Option<String>, |
8faf50e0 | 216 | llvm_tools_version: Option<String>, |
b7449926 | 217 | lldb_version: Option<String>, |
0731742a | 218 | miri_version: Option<String>, |
abe05a73 | 219 | |
ea8adc8c XL |
220 | rust_git_commit_hash: Option<String>, |
221 | cargo_git_commit_hash: Option<String>, | |
222 | rls_git_commit_hash: Option<String>, | |
8faf50e0 | 223 | clippy_git_commit_hash: Option<String>, |
abe05a73 | 224 | rustfmt_git_commit_hash: Option<String>, |
8faf50e0 | 225 | llvm_tools_git_commit_hash: Option<String>, |
b7449926 | 226 | lldb_git_commit_hash: Option<String>, |
0731742a | 227 | miri_git_commit_hash: Option<String>, |
b7449926 XL |
228 | |
229 | should_sign: bool, | |
32a655c1 SL |
230 | } |
231 | ||
232 | fn main() { | |
b7449926 XL |
233 | // Avoid signing packages while manually testing |
234 | // Do NOT set this envvar in CI | |
235 | let should_sign = env::var("BUILD_MANIFEST_DISABLE_SIGNING").is_err(); | |
236 | ||
237 | // Safety check to ensure signing is always enabled on CI | |
238 | // The CI environment variable is set by both Travis and AppVeyor | |
239 | if !should_sign && env::var("CI").is_ok() { | |
240 | println!("The 'BUILD_MANIFEST_DISABLE_SIGNING' env var can't be enabled on CI."); | |
241 | println!("If you're not running this on CI, unset the 'CI' env var."); | |
242 | panic!(); | |
243 | } | |
244 | ||
32a655c1 SL |
245 | let mut args = env::args().skip(1); |
246 | let input = PathBuf::from(args.next().unwrap()); | |
247 | let output = PathBuf::from(args.next().unwrap()); | |
248 | let date = args.next().unwrap(); | |
8bb4bdeb | 249 | let rust_release = args.next().unwrap(); |
0731742a | 250 | let s3_address = args.next().unwrap(); |
8bb4bdeb | 251 | let cargo_release = args.next().unwrap(); |
3b2f2976 | 252 | let rls_release = args.next().unwrap(); |
8faf50e0 | 253 | let clippy_release = args.next().unwrap(); |
0731742a | 254 | let miri_release = args.next().unwrap(); |
abe05a73 | 255 | let rustfmt_release = args.next().unwrap(); |
8faf50e0 | 256 | let llvm_tools_release = args.next().unwrap(); |
b7449926 | 257 | let lldb_release = args.next().unwrap(); |
b7449926 XL |
258 | |
259 | // Do not ask for a passphrase while manually testing | |
32a655c1 | 260 | let mut passphrase = String::new(); |
b7449926 XL |
261 | if should_sign { |
262 | t!(io::stdin().read_to_string(&mut passphrase)); | |
263 | } | |
32a655c1 SL |
264 | |
265 | Builder { | |
3b2f2976 XL |
266 | rust_release, |
267 | cargo_release, | |
268 | rls_release, | |
8faf50e0 | 269 | clippy_release, |
abe05a73 | 270 | rustfmt_release, |
8faf50e0 | 271 | llvm_tools_release, |
b7449926 | 272 | lldb_release, |
0731742a | 273 | miri_release, |
abe05a73 | 274 | |
3b2f2976 XL |
275 | input, |
276 | output, | |
32a655c1 | 277 | gpg_passphrase: passphrase, |
cc61c64b | 278 | digests: BTreeMap::new(), |
3b2f2976 XL |
279 | s3_address, |
280 | date, | |
abe05a73 XL |
281 | |
282 | rust_version: None, | |
283 | cargo_version: None, | |
284 | rls_version: None, | |
8faf50e0 | 285 | clippy_version: None, |
abe05a73 | 286 | rustfmt_version: None, |
8faf50e0 | 287 | llvm_tools_version: None, |
b7449926 | 288 | lldb_version: None, |
0731742a | 289 | miri_version: None, |
abe05a73 | 290 | |
ea8adc8c XL |
291 | rust_git_commit_hash: None, |
292 | cargo_git_commit_hash: None, | |
293 | rls_git_commit_hash: None, | |
8faf50e0 | 294 | clippy_git_commit_hash: None, |
abe05a73 | 295 | rustfmt_git_commit_hash: None, |
8faf50e0 | 296 | llvm_tools_git_commit_hash: None, |
b7449926 | 297 | lldb_git_commit_hash: None, |
0731742a | 298 | miri_git_commit_hash: None, |
b7449926 XL |
299 | |
300 | should_sign, | |
32a655c1 SL |
301 | }.build(); |
302 | } | |
303 | ||
304 | impl Builder { | |
305 | fn build(&mut self) { | |
306 | self.rust_version = self.version("rust", "x86_64-unknown-linux-gnu"); | |
307 | self.cargo_version = self.version("cargo", "x86_64-unknown-linux-gnu"); | |
3b2f2976 | 308 | self.rls_version = self.version("rls", "x86_64-unknown-linux-gnu"); |
8faf50e0 | 309 | self.clippy_version = self.version("clippy", "x86_64-unknown-linux-gnu"); |
abe05a73 | 310 | self.rustfmt_version = self.version("rustfmt", "x86_64-unknown-linux-gnu"); |
8faf50e0 | 311 | self.llvm_tools_version = self.version("llvm-tools", "x86_64-unknown-linux-gnu"); |
b7449926 XL |
312 | // lldb is only built for macOS. |
313 | self.lldb_version = self.version("lldb", "x86_64-apple-darwin"); | |
0731742a | 314 | self.miri_version = self.version("miri", "x86_64-unknown-linux-gnu"); |
abe05a73 | 315 | |
ea8adc8c XL |
316 | self.rust_git_commit_hash = self.git_commit_hash("rust", "x86_64-unknown-linux-gnu"); |
317 | self.cargo_git_commit_hash = self.git_commit_hash("cargo", "x86_64-unknown-linux-gnu"); | |
318 | self.rls_git_commit_hash = self.git_commit_hash("rls", "x86_64-unknown-linux-gnu"); | |
8faf50e0 | 319 | self.clippy_git_commit_hash = self.git_commit_hash("clippy", "x86_64-unknown-linux-gnu"); |
abe05a73 | 320 | self.rustfmt_git_commit_hash = self.git_commit_hash("rustfmt", "x86_64-unknown-linux-gnu"); |
8faf50e0 XL |
321 | self.llvm_tools_git_commit_hash = self.git_commit_hash("llvm-tools", |
322 | "x86_64-unknown-linux-gnu"); | |
b7449926 | 323 | self.lldb_git_commit_hash = self.git_commit_hash("lldb", "x86_64-unknown-linux-gnu"); |
0731742a | 324 | self.miri_git_commit_hash = self.git_commit_hash("miri", "x86_64-unknown-linux-gnu"); |
32a655c1 SL |
325 | |
326 | self.digest_and_sign(); | |
3b2f2976 | 327 | let manifest = self.build_manifest(); |
ea8adc8c | 328 | self.write_channel_files(&self.rust_release, &manifest); |
8bb4bdeb XL |
329 | |
330 | if self.rust_release != "beta" && self.rust_release != "nightly" { | |
ea8adc8c | 331 | self.write_channel_files("stable", &manifest); |
32a655c1 SL |
332 | } |
333 | } | |
334 | ||
335 | fn digest_and_sign(&mut self) { | |
336 | for file in t!(self.input.read_dir()).map(|e| t!(e).path()) { | |
337 | let filename = file.file_name().unwrap().to_str().unwrap(); | |
338 | let digest = self.hash(&file); | |
339 | self.sign(&file); | |
340 | assert!(self.digests.insert(filename.to_string(), digest).is_none()); | |
341 | } | |
342 | } | |
343 | ||
344 | fn build_manifest(&mut self) -> Manifest { | |
345 | let mut manifest = Manifest { | |
346 | manifest_version: "2".to_string(), | |
347 | date: self.date.to_string(), | |
cc61c64b | 348 | pkg: BTreeMap::new(), |
ea8adc8c | 349 | renames: BTreeMap::new(), |
0731742a | 350 | profiles: BTreeMap::new(), |
32a655c1 SL |
351 | }; |
352 | ||
353 | self.package("rustc", &mut manifest.pkg, HOSTS); | |
354 | self.package("cargo", &mut manifest.pkg, HOSTS); | |
355 | self.package("rust-mingw", &mut manifest.pkg, MINGW); | |
356 | self.package("rust-std", &mut manifest.pkg, TARGETS); | |
b7449926 | 357 | self.package("rust-docs", &mut manifest.pkg, DOCS_TARGETS); |
32a655c1 | 358 | self.package("rust-src", &mut manifest.pkg, &["*"]); |
ea8adc8c | 359 | self.package("rls-preview", &mut manifest.pkg, HOSTS); |
8faf50e0 | 360 | self.package("clippy-preview", &mut manifest.pkg, HOSTS); |
abe05a73 | 361 | self.package("rustfmt-preview", &mut manifest.pkg, HOSTS); |
cc61c64b | 362 | self.package("rust-analysis", &mut manifest.pkg, TARGETS); |
8faf50e0 | 363 | self.package("llvm-tools-preview", &mut manifest.pkg, TARGETS); |
b7449926 | 364 | self.package("lldb-preview", &mut manifest.pkg, TARGETS); |
8bb4bdeb | 365 | |
0731742a XL |
366 | self.profile("minimal", |
367 | &mut manifest.profiles, | |
368 | &["rustc", "cargo", "rust-std", "rust-mingw"]); | |
369 | self.profile("default", | |
370 | &mut manifest.profiles, | |
371 | &["rustc", "cargo", "rust-std", "rust-mingw", | |
372 | "rust-docs", "rustfmt-preview", "clippy-preview"]); | |
373 | self.profile("complete", | |
374 | &mut manifest.profiles, | |
375 | &["rustc", "cargo", "rust-std", "rust-mingw", | |
376 | "rust-docs", "rustfmt-preview", "clippy-preview", | |
377 | "rls-preview", "rust-src", "llvm-tools-preview", | |
378 | "lldb-preview", "rust-analysis"]); | |
379 | ||
b7449926 | 380 | manifest.renames.insert("rls".to_owned(), Rename { to: "rls-preview".to_owned() }); |
13cf67c4 XL |
381 | manifest.renames.insert("rustfmt".to_owned(), Rename { to: "rustfmt-preview".to_owned() }); |
382 | manifest.renames.insert("clippy".to_owned(), Rename { to: "clippy-preview".to_owned() }); | |
ea8adc8c | 383 | |
32a655c1 | 384 | let mut pkg = Package { |
abe05a73 XL |
385 | version: self.cached_version("rust") |
386 | .as_ref() | |
387 | .expect("Couldn't find Rust version") | |
388 | .clone(), | |
ea8adc8c | 389 | git_commit_hash: self.cached_git_commit_hash("rust").clone(), |
cc61c64b | 390 | target: BTreeMap::new(), |
32a655c1 SL |
391 | }; |
392 | for host in HOSTS { | |
393 | let filename = self.filename("rust", host); | |
394 | let digest = match self.digests.remove(&filename) { | |
395 | Some(digest) => digest, | |
396 | None => { | |
7cac9316 | 397 | pkg.target.insert(host.to_string(), Target::unavailable()); |
32a655c1 SL |
398 | continue |
399 | } | |
400 | }; | |
7cac9316 XL |
401 | let xz_filename = filename.replace(".tar.gz", ".tar.xz"); |
402 | let xz_digest = self.digests.remove(&xz_filename); | |
32a655c1 SL |
403 | let mut components = Vec::new(); |
404 | let mut extensions = Vec::new(); | |
405 | ||
8bb4bdeb XL |
406 | // rustc/rust-std/cargo/docs are all required, and so is rust-mingw |
407 | // if it's available for the target. | |
32a655c1 SL |
408 | components.extend(vec![ |
409 | Component { pkg: "rustc".to_string(), target: host.to_string() }, | |
410 | Component { pkg: "rust-std".to_string(), target: host.to_string() }, | |
411 | Component { pkg: "cargo".to_string(), target: host.to_string() }, | |
8bb4bdeb | 412 | Component { pkg: "rust-docs".to_string(), target: host.to_string() }, |
32a655c1 SL |
413 | ]); |
414 | if host.contains("pc-windows-gnu") { | |
415 | components.push(Component { | |
416 | pkg: "rust-mingw".to_string(), | |
417 | target: host.to_string(), | |
418 | }); | |
419 | } | |
420 | ||
b7449926 XL |
421 | // Tools are always present in the manifest, but might be marked as unavailable if they |
422 | // weren't built | |
423 | extensions.extend(vec![ | |
424 | Component { pkg: "clippy-preview".to_string(), target: host.to_string() }, | |
425 | Component { pkg: "rls-preview".to_string(), target: host.to_string() }, | |
426 | Component { pkg: "rustfmt-preview".to_string(), target: host.to_string() }, | |
427 | Component { pkg: "llvm-tools-preview".to_string(), target: host.to_string() }, | |
428 | Component { pkg: "lldb-preview".to_string(), target: host.to_string() }, | |
429 | Component { pkg: "rust-analysis".to_string(), target: host.to_string() }, | |
430 | ]); | |
431 | ||
32a655c1 SL |
432 | for target in TARGETS { |
433 | if target != host { | |
434 | extensions.push(Component { | |
435 | pkg: "rust-std".to_string(), | |
436 | target: target.to_string(), | |
437 | }); | |
438 | } | |
439 | } | |
440 | extensions.push(Component { | |
441 | pkg: "rust-src".to_string(), | |
442 | target: "*".to_string(), | |
443 | }); | |
444 | ||
564c78a2 XL |
445 | // If the components/extensions don't actually exist for this |
446 | // particular host/target combination then nix it entirely from our | |
447 | // lists. | |
448 | { | |
449 | let has_component = |c: &Component| { | |
450 | if c.target == "*" { | |
451 | return true | |
452 | } | |
453 | let pkg = match manifest.pkg.get(&c.pkg) { | |
454 | Some(p) => p, | |
455 | None => return false, | |
456 | }; | |
b7449926 | 457 | pkg.target.get(&c.target).is_some() |
564c78a2 XL |
458 | }; |
459 | extensions.retain(&has_component); | |
460 | components.retain(&has_component); | |
461 | } | |
462 | ||
32a655c1 SL |
463 | pkg.target.insert(host.to_string(), Target { |
464 | available: true, | |
7cac9316 | 465 | url: Some(self.url(&filename)), |
8bb4bdeb | 466 | hash: Some(digest), |
7cac9316 XL |
467 | xz_url: xz_digest.as_ref().map(|_| self.url(&xz_filename)), |
468 | xz_hash: xz_digest, | |
32a655c1 SL |
469 | components: Some(components), |
470 | extensions: Some(extensions), | |
471 | }); | |
472 | } | |
473 | manifest.pkg.insert("rust".to_string(), pkg); | |
474 | ||
9fa01778 | 475 | manifest |
32a655c1 SL |
476 | } |
477 | ||
0731742a XL |
478 | fn profile(&mut self, |
479 | profile_name: &str, | |
480 | dst: &mut BTreeMap<String, Vec<String>>, | |
481 | pkgs: &[&str]) { | |
482 | dst.insert(profile_name.to_owned(), pkgs.iter().map(|s| (*s).to_owned()).collect()); | |
483 | } | |
484 | ||
32a655c1 SL |
485 | fn package(&mut self, |
486 | pkgname: &str, | |
cc61c64b | 487 | dst: &mut BTreeMap<String, Package>, |
32a655c1 | 488 | targets: &[&str]) { |
b7449926 XL |
489 | let (version, is_present) = match *self.cached_version(pkgname) { |
490 | Some(ref version) => (version.clone(), true), | |
491 | None => (String::new(), false), | |
abe05a73 XL |
492 | }; |
493 | ||
32a655c1 | 494 | let targets = targets.iter().map(|name| { |
b7449926 XL |
495 | if is_present { |
496 | let filename = self.filename(pkgname, name); | |
497 | let digest = match self.digests.remove(&filename) { | |
498 | Some(digest) => digest, | |
499 | None => return (name.to_string(), Target::unavailable()), | |
500 | }; | |
501 | let xz_filename = filename.replace(".tar.gz", ".tar.xz"); | |
502 | let xz_digest = self.digests.remove(&xz_filename); | |
503 | ||
504 | (name.to_string(), Target { | |
505 | available: true, | |
506 | url: Some(self.url(&filename)), | |
507 | hash: Some(digest), | |
508 | xz_url: xz_digest.as_ref().map(|_| self.url(&xz_filename)), | |
509 | xz_hash: xz_digest, | |
510 | components: None, | |
511 | extensions: None, | |
512 | }) | |
513 | } else { | |
514 | // If the component is not present for this build add it anyway but mark it as | |
515 | // unavailable -- this way rustup won't allow upgrades without --force | |
516 | (name.to_string(), Target { | |
517 | available: false, | |
518 | url: None, | |
519 | hash: None, | |
520 | xz_url: None, | |
521 | xz_hash: None, | |
522 | components: None, | |
523 | extensions: None, | |
524 | }) | |
525 | } | |
32a655c1 SL |
526 | }).collect(); |
527 | ||
528 | dst.insert(pkgname.to_string(), Package { | |
abe05a73 | 529 | version, |
ea8adc8c | 530 | git_commit_hash: self.cached_git_commit_hash(pkgname).clone(), |
32a655c1 SL |
531 | target: targets, |
532 | }); | |
533 | } | |
534 | ||
7cac9316 | 535 | fn url(&self, filename: &str) -> String { |
32a655c1 SL |
536 | format!("{}/{}/{}", |
537 | self.s3_address, | |
538 | self.date, | |
7cac9316 | 539 | filename) |
32a655c1 SL |
540 | } |
541 | ||
542 | fn filename(&self, component: &str, target: &str) -> String { | |
543 | if component == "rust-src" { | |
8bb4bdeb | 544 | format!("rust-src-{}.tar.gz", self.rust_release) |
32a655c1 | 545 | } else if component == "cargo" { |
8bb4bdeb | 546 | format!("cargo-{}-{}.tar.gz", self.cargo_release, target) |
3b2f2976 XL |
547 | } else if component == "rls" || component == "rls-preview" { |
548 | format!("rls-{}-{}.tar.gz", self.rls_release, target) | |
8faf50e0 XL |
549 | } else if component == "clippy" || component == "clippy-preview" { |
550 | format!("clippy-{}-{}.tar.gz", self.clippy_release, target) | |
abe05a73 XL |
551 | } else if component == "rustfmt" || component == "rustfmt-preview" { |
552 | format!("rustfmt-{}-{}.tar.gz", self.rustfmt_release, target) | |
8faf50e0 XL |
553 | } else if component == "llvm-tools" || component == "llvm-tools-preview" { |
554 | format!("llvm-tools-{}-{}.tar.gz", self.llvm_tools_release, target) | |
b7449926 XL |
555 | } else if component == "lldb" || component == "lldb-preview" { |
556 | format!("lldb-{}-{}.tar.gz", self.lldb_release, target) | |
0731742a XL |
557 | } else if component == "miri" || component == "miri-preview" { |
558 | format!("miri-{}-{}.tar.gz", self.miri_release, target) | |
32a655c1 | 559 | } else { |
8bb4bdeb | 560 | format!("{}-{}-{}.tar.gz", component, self.rust_release, target) |
32a655c1 SL |
561 | } |
562 | } | |
563 | ||
abe05a73 | 564 | fn cached_version(&self, component: &str) -> &Option<String> { |
32a655c1 SL |
565 | if component == "cargo" { |
566 | &self.cargo_version | |
3b2f2976 XL |
567 | } else if component == "rls" || component == "rls-preview" { |
568 | &self.rls_version | |
8faf50e0 XL |
569 | } else if component == "clippy" || component == "clippy-preview" { |
570 | &self.clippy_version | |
abe05a73 XL |
571 | } else if component == "rustfmt" || component == "rustfmt-preview" { |
572 | &self.rustfmt_version | |
8faf50e0 XL |
573 | } else if component == "llvm-tools" || component == "llvm-tools-preview" { |
574 | &self.llvm_tools_version | |
b7449926 XL |
575 | } else if component == "lldb" || component == "lldb-preview" { |
576 | &self.lldb_version | |
0731742a XL |
577 | } else if component == "miri" || component == "miri-preview" { |
578 | &self.miri_version | |
32a655c1 SL |
579 | } else { |
580 | &self.rust_version | |
581 | } | |
582 | } | |
583 | ||
ea8adc8c XL |
584 | fn cached_git_commit_hash(&self, component: &str) -> &Option<String> { |
585 | if component == "cargo" { | |
586 | &self.cargo_git_commit_hash | |
587 | } else if component == "rls" || component == "rls-preview" { | |
588 | &self.rls_git_commit_hash | |
8faf50e0 XL |
589 | } else if component == "clippy" || component == "clippy-preview" { |
590 | &self.clippy_git_commit_hash | |
abe05a73 XL |
591 | } else if component == "rustfmt" || component == "rustfmt-preview" { |
592 | &self.rustfmt_git_commit_hash | |
8faf50e0 XL |
593 | } else if component == "llvm-tools" || component == "llvm-tools-preview" { |
594 | &self.llvm_tools_git_commit_hash | |
b7449926 XL |
595 | } else if component == "lldb" || component == "lldb-preview" { |
596 | &self.lldb_git_commit_hash | |
0731742a XL |
597 | } else if component == "miri" || component == "miri-preview" { |
598 | &self.miri_git_commit_hash | |
ea8adc8c XL |
599 | } else { |
600 | &self.rust_git_commit_hash | |
601 | } | |
602 | } | |
603 | ||
abe05a73 | 604 | fn version(&self, component: &str, target: &str) -> Option<String> { |
32a655c1 SL |
605 | let mut cmd = Command::new("tar"); |
606 | let filename = self.filename(component, target); | |
607 | cmd.arg("xf") | |
608 | .arg(self.input.join(&filename)) | |
609 | .arg(format!("{}/version", filename.replace(".tar.gz", ""))) | |
610 | .arg("-O"); | |
ea8adc8c | 611 | let output = t!(cmd.output()); |
abe05a73 XL |
612 | if output.status.success() { |
613 | Some(String::from_utf8_lossy(&output.stdout).trim().to_string()) | |
614 | } else { | |
615 | // Perhaps we didn't build this package. | |
616 | None | |
ea8adc8c | 617 | } |
ea8adc8c XL |
618 | } |
619 | ||
620 | fn git_commit_hash(&self, component: &str, target: &str) -> Option<String> { | |
621 | let mut cmd = Command::new("tar"); | |
622 | let filename = self.filename(component, target); | |
623 | cmd.arg("xf") | |
624 | .arg(self.input.join(&filename)) | |
625 | .arg(format!("{}/git-commit-hash", filename.replace(".tar.gz", ""))) | |
626 | .arg("-O"); | |
627 | let output = t!(cmd.output()); | |
628 | if output.status.success() { | |
629 | Some(String::from_utf8_lossy(&output.stdout).trim().to_string()) | |
630 | } else { | |
ea8adc8c | 631 | None |
32a655c1 | 632 | } |
32a655c1 SL |
633 | } |
634 | ||
635 | fn hash(&self, path: &Path) -> String { | |
636 | let sha = t!(Command::new("shasum") | |
637 | .arg("-a").arg("256") | |
638 | .arg(path.file_name().unwrap()) | |
639 | .current_dir(path.parent().unwrap()) | |
640 | .output()); | |
641 | assert!(sha.status.success()); | |
642 | ||
643 | let filename = path.file_name().unwrap().to_str().unwrap(); | |
644 | let sha256 = self.output.join(format!("{}.sha256", filename)); | |
0731742a | 645 | t!(fs::write(&sha256, &sha.stdout)); |
32a655c1 SL |
646 | |
647 | let stdout = String::from_utf8_lossy(&sha.stdout); | |
648 | stdout.split_whitespace().next().unwrap().to_string() | |
649 | } | |
650 | ||
651 | fn sign(&self, path: &Path) { | |
b7449926 XL |
652 | if !self.should_sign { |
653 | return; | |
654 | } | |
655 | ||
32a655c1 SL |
656 | let filename = path.file_name().unwrap().to_str().unwrap(); |
657 | let asc = self.output.join(format!("{}.asc", filename)); | |
658 | println!("signing: {:?}", path); | |
659 | let mut cmd = Command::new("gpg"); | |
69743fb6 XL |
660 | cmd.arg("--pinentry-mode=loopback") |
661 | .arg("--no-tty") | |
32a655c1 | 662 | .arg("--yes") |
69743fb6 | 663 | .arg("--batch") |
32a655c1 | 664 | .arg("--passphrase-fd").arg("0") |
ea8adc8c | 665 | .arg("--personal-digest-preferences").arg("SHA512") |
32a655c1 SL |
666 | .arg("--armor") |
667 | .arg("--output").arg(&asc) | |
668 | .arg("--detach-sign").arg(path) | |
669 | .stdin(Stdio::piped()); | |
670 | let mut child = t!(cmd.spawn()); | |
671 | t!(child.stdin.take().unwrap().write_all(self.gpg_passphrase.as_bytes())); | |
672 | assert!(t!(child.wait()).success()); | |
673 | } | |
674 | ||
ea8adc8c XL |
675 | fn write_channel_files(&self, channel_name: &str, manifest: &Manifest) { |
676 | self.write(&toml::to_string(&manifest).unwrap(), channel_name, ".toml"); | |
677 | self.write(&manifest.date, channel_name, "-date.txt"); | |
678 | self.write(manifest.pkg["rust"].git_commit_hash.as_ref().unwrap(), | |
679 | channel_name, "-git-commit-hash.txt"); | |
32a655c1 | 680 | } |
32a655c1 | 681 | |
ea8adc8c XL |
682 | fn write(&self, contents: &str, channel_name: &str, suffix: &str) { |
683 | let dst = self.output.join(format!("channel-rust-{}{}", channel_name, suffix)); | |
0731742a | 684 | t!(fs::write(&dst, contents)); |
8bb4bdeb XL |
685 | self.hash(&dst); |
686 | self.sign(&dst); | |
32a655c1 SL |
687 | } |
688 | } |