1 //! This build script ensures that clippy is not compiled with an
2 //! incompatible version of rust. It will panic with a descriptive
3 //! error message instead.
5 //! We specifially want to ensure that clippy is only built with a
6 //! rustc version that is newer or equal to the one specified in the
7 //! `min_version.txt` file.
9 //! `min_version.txt` is in the repo but also in the `.gitignore` to
10 //! make sure that it is not updated manually by accident. Only CI
11 //! should update that file.
13 //! This build script was originally taken from the Rocket web framework:
14 //! https://github.com/SergioBenitez/Rocket
16 extern crate rustc_version;
17 extern crate ansi_term;
20 use rustc_version::{version_meta, version_meta_for, Channel, Version, VersionMeta};
21 use ansi_term::Colour::Red;
24 let string = include_str!("min_version.txt");
25 let min_version_meta = version_meta_for(string)
26 .expect("Could not parse version string in min_version.txt");
27 let current_version_meta = version_meta()
28 .expect("Could not retrieve current rustc version information from ENV");
30 let min_version = min_version_meta.clone().semver;
31 let min_date_str = min_version_meta.clone().commit_date
32 .expect("min_version.txt does not contain a rustc commit date");
34 let current_version = current_version_meta.clone().semver;
35 let current_date_str = current_version_meta.clone().commit_date
36 .expect("current rustc version information does not contain a rustc commit date");
38 let print_version_err = |version: &Version, date: &str| {
39 eprintln!("> {} {}. {} {}.\n",
40 "Installed rustc version is:",
41 format!("{} ({})", version, date),
42 "Minimum required rustc version:",
43 format!("{} ({})", min_version, min_date_str));
46 if !correct_channel(¤t_version_meta) {
48 Red.bold().paint("error:"),
49 "clippy requires a nightly version of Rust.");
50 print_version_err(¤t_version, &*current_date_str);
53 "https://github.com/rust-lang-nursery/rust-clippy#usage",
54 ") for more information.");
55 panic!("Aborting compilation due to incompatible compiler.")
58 let current_date = str_to_ymd(¤t_date_str).unwrap();
59 let min_date = str_to_ymd(&min_date_str).unwrap();
61 if current_date < min_date {
63 Red.bold().paint("error:"),
64 "clippy does not support this version of rustc nightly.");
68 "` or your preferred method to update Rust.");
69 print_version_err(¤t_version, &*current_date_str);
70 panic!("Aborting compilation due to incompatible compiler.")
73 // Forward the profile to the main compilation
74 println!("cargo:rustc-env=PROFILE={}", env::var("PROFILE").unwrap());
75 // Don't rebuild even if nothing changed
76 println!("cargo:rerun-if-changed=build.rs");
79 fn correct_channel(version_meta: &VersionMeta) -> bool {
80 match version_meta.channel {
81 Channel::Stable | Channel::Beta => {
84 Channel::Nightly | Channel::Dev => {
90 /// Convert a string of %Y-%m-%d to a single u32 maintaining ordering.
91 fn str_to_ymd(ymd: &str) -> Option<u32> {
92 let ymd: Vec<u32> = ymd.split("-").filter_map(|s| s.parse::<u32>().ok()).collect();
97 let (y, m, d) = (ymd[0], ymd[1], ymd[2]);
98 Some((y << 9) | (m << 5) | d)