Skip to content

Commit ad438b3

Browse files
authored
Merge pull request #2733 from phansch/build_script
Add rustc version check to build script
2 parents 92a6f62 + c0a0ddd commit ad438b3

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,6 @@ helper.txt
3131
*.iml
3232
.vscode
3333
.idea
34+
35+
# Used by the Clippy build script
36+
min_version.txt

Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,9 @@ clippy-mini-macro-test = { version = "0.2", path = "mini-macro" }
5151
serde = "1.0"
5252
derive-new = "0.5"
5353

54+
[build-dependencies]
55+
rustc_version = "0.2.2"
56+
ansi_term = "0.11"
57+
5458
[features]
5559
debugging = []

build.rs

+91
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,99 @@
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.
4+
//!
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.
8+
//!
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.
12+
//!
13+
//! This build script was originally taken from the Rocket web framework:
14+
//! https://github.com/SergioBenitez/Rocket
15+
16+
extern crate rustc_version;
17+
extern crate ansi_term;
18+
119
use std::env;
20+
use rustc_version::{version_meta, version_meta_for, Channel, Version, VersionMeta};
21+
use ansi_term::Colour::Red;
222

323
fn main() {
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");
29+
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");
33+
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");
37+
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));
44+
};
45+
46+
if !correct_channel(&current_version_meta) {
47+
eprintln!("\n{} {}",
48+
Red.bold().paint("error:"),
49+
"clippy requires a nightly version of Rust.");
50+
print_version_err(&current_version, &*current_date_str);
51+
eprintln!("{}{}{}",
52+
"See the README (",
53+
"https://github.com/rust-lang-nursery/rust-clippy#usage",
54+
") for more information.");
55+
panic!("Aborting compilation due to incompatible compiler.")
56+
}
57+
58+
let current_date = str_to_ymd(&current_date_str).unwrap();
59+
let min_date = str_to_ymd(&min_date_str).unwrap();
60+
61+
if current_date < min_date {
62+
eprintln!("\n{} {}",
63+
Red.bold().paint("error:"),
64+
"clippy does not support this version of rustc nightly.");
65+
eprintln!("> {}{}{}",
66+
"Use `",
67+
"rustup update",
68+
"` or your preferred method to update Rust.");
69+
print_version_err(&current_version, &*current_date_str);
70+
panic!("Aborting compilation due to incompatible compiler.")
71+
}
72+
473
// Forward the profile to the main compilation
574
println!("cargo:rustc-env=PROFILE={}", env::var("PROFILE").unwrap());
675
// Don't rebuild even if nothing changed
776
println!("cargo:rerun-if-changed=build.rs");
877
}
78+
79+
fn correct_channel(version_meta: &VersionMeta) -> bool {
80+
match version_meta.channel {
81+
Channel::Stable | Channel::Beta => {
82+
false
83+
},
84+
Channel::Nightly | Channel::Dev => {
85+
true
86+
}
87+
}
88+
}
89+
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();
93+
if ymd.len() != 3 {
94+
return None
95+
}
96+
97+
let (y, m, d) = (ymd[0], ymd[1], ymd[2]);
98+
Some((y << 9) | (m << 5) | d)
99+
}

min_version.txt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
rustc 1.27.0-nightly (e82261dfb 2018-05-03)
2+
binary: rustc
3+
commit-hash: e82261dfbb5feaa2d28d2b138f4aabb2aa52c94b
4+
commit-date: 2018-05-03
5+
host: x86_64-unknown-linux-gnu
6+
release: 1.27.0-nightly
7+
LLVM version: 6.0

0 commit comments

Comments
 (0)