forked from rust-lang/rust-clippy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.rs
110 lines (96 loc) · 3.89 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! This build script ensures that Clippy is not compiled with an
//! incompatible version of rust. It will panic with a descriptive
//! error message instead.
//!
//! We specifially want to ensure that Clippy is only built with a
//! rustc version that is newer or equal to the one specified in the
//! `min_version.txt` file.
//!
//! `min_version.txt` is in the repo but also in the `.gitignore` to
//! make sure that it is not updated manually by accident. Only CI
//! should update that file.
//!
//! This build script was originally taken from the Rocket web framework:
//! https://github.com/SergioBenitez/Rocket
use ansi_term::Colour::Red;
use rustc_version::{version_meta, version_meta_for, Channel, Version, VersionMeta};
use std::env;
fn main() {
check_rustc_version();
// Forward the profile to the main compilation
println!("cargo:rustc-env=PROFILE={}", env::var("PROFILE").unwrap());
// Don't rebuild even if nothing changed
println!("cargo:rerun-if-changed=build.rs");
}
fn check_rustc_version() {
let string = include_str!("min_version.txt");
let min_version_meta = version_meta_for(string).expect("Could not parse version string in min_version.txt");
let current_version_meta = version_meta().expect("Could not retrieve current rustc version information from ENV");
let min_version = min_version_meta.clone().semver;
let min_date_str = min_version_meta
.clone()
.commit_date
.expect("min_version.txt does not contain a rustc commit date");
// Dev channel (rustc built from git) does not have any date or commit information in rustc -vV
// `current_version_meta.commit_date` would crash, so we return early here.
if current_version_meta.channel == Channel::Dev {
return;
}
let current_version = current_version_meta.clone().semver;
let current_date_str = current_version_meta
.clone()
.commit_date
.expect("current rustc version information does not contain a rustc commit date");
let print_version_err = |version: &Version, date: &str| {
eprintln!(
"> {} {}. {} {}.\n",
"Installed rustc version is:",
format!("{} ({})", version, date),
"Minimum required rustc version:",
format!("{} ({})", min_version, min_date_str)
);
};
if !correct_channel(¤t_version_meta) {
eprintln!(
"\n{} {}",
Red.bold().paint("error:"),
"Clippy requires a nightly version of Rust."
);
print_version_err(¤t_version, &*current_date_str);
eprintln!(
"{}{}{}",
"See the README (", "https://github.com/rust-lang-nursery/rust-clippy#usage", ") for more information."
);
panic!("Aborting compilation due to incompatible compiler.")
}
let current_date = str_to_ymd(¤t_date_str).unwrap();
let min_date = str_to_ymd(&min_date_str).unwrap();
if current_date < min_date {
eprintln!(
"\n{} {}",
Red.bold().paint("error:"),
"Clippy does not support this version of rustc nightly."
);
eprintln!(
"> {}{}{}",
"Use `", "rustup update", "` or your preferred method to update Rust."
);
print_version_err(¤t_version, &*current_date_str);
panic!("Aborting compilation due to incompatible compiler.")
}
}
fn correct_channel(version_meta: &VersionMeta) -> bool {
match version_meta.channel {
Channel::Stable | Channel::Beta => false,
Channel::Nightly | Channel::Dev => true,
}
}
/// Convert a string of %Y-%m-%d to a single u32 maintaining ordering.
fn str_to_ymd(ymd: &str) -> Option<u32> {
let ymd: Vec<u32> = ymd.split("-").filter_map(|s| s.parse::<u32>().ok()).collect();
if ymd.len() != 3 {
return None;
}
let (y, m, d) = (ymd[0], ymd[1], ymd[2]);
Some((y << 9) | (m << 5) | d)
}