Skip to content

Commit 1c4fd85

Browse files
Add a CI check that all crates in the workspace have a consistent version.
1 parent d31bbe2 commit 1c4fd85

File tree

4 files changed

+75
-0
lines changed

4 files changed

+75
-0
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ env:
1010
- CARGO_INCREMENTAL=0
1111
install: skip
1212
script:
13+
- cargo run --bin version_checker || exit 1
1314
- cargo check --verbose --target powerpc64-unknown-linux-gnu --lib --bins --tests || exit 1
1415
- cargo build --verbose --all || exit 1
1516
- cargo test --verbose --all

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ members = [
88
"mmview",
99
"stack_collapse",
1010
"summarize",
11+
"version_checker",
1112
]

version_checker/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "version_checker"
3+
version = "0.7.1"
4+
authors = ["Michael Woerister <michaelwoerister@posteo>"]
5+
edition = "2018"
6+
license = "MIT OR Apache-2.0"
7+
8+
[dependencies]
9+
regex = "1"
10+
glob = "0.3.0"

version_checker/src/main.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// This is a small tool for making sure that we keep versions between all crates
2+
// in the workspace consistent. It just panics if it finds an error and is
3+
// supposed to be run as part of CI.
4+
5+
use glob::glob;
6+
use regex::Regex;
7+
use std::collections::BTreeMap;
8+
use std::path::{Path, PathBuf};
9+
10+
fn main() {
11+
eprint!(
12+
"Checking Cargo workspace \"{}\" for crate version consistency ... ",
13+
Path::new(".").canonicalize().unwrap().display()
14+
);
15+
16+
let workspace_cargo_toml_txt = std::fs::read_to_string("Cargo.toml").unwrap();
17+
18+
if !workspace_cargo_toml_txt.trim().starts_with("[workspace]") {
19+
panic!(
20+
"Could not find workspace Cargo.toml at {}.\n\
21+
This tool has to be executed in the top-level directory \
22+
of the Cargo workspace.",
23+
Path::new("Cargo.toml").canonicalize().unwrap().display()
24+
);
25+
}
26+
27+
let mut versions: BTreeMap<PathBuf, String> = BTreeMap::new();
28+
29+
let version_regex = Regex::new("version\\s*=\\s*\"(.*)\"").unwrap();
30+
31+
for entry in glob("./*/Cargo.toml").expect("Failed to read glob pattern") {
32+
let cargo_toml_path = entry.unwrap();
33+
let cargo_toml_txt = std::fs::read_to_string(&cargo_toml_path).unwrap();
34+
35+
for line in cargo_toml_txt.lines() {
36+
if let Some(caps) = version_regex.captures(line) {
37+
let version = caps[1].to_string();
38+
versions.insert(cargo_toml_path.clone(), version);
39+
break;
40+
}
41+
}
42+
43+
if !versions.contains_key(&cargo_toml_path) {
44+
panic!(
45+
"Could not find `version` field in {}",
46+
cargo_toml_path.display()
47+
);
48+
}
49+
}
50+
51+
let reference_version = versions.values().next().unwrap();
52+
53+
if !versions.values().all(|v| v == reference_version) {
54+
eprintln!("Crate versions found:");
55+
for (cargo_toml_path, version) in &versions {
56+
eprintln!(" {} = {}", cargo_toml_path.display(), version);
57+
}
58+
59+
panic!("Not all crate versions are the same, please keep them in sync!");
60+
}
61+
62+
eprintln!("check passed");
63+
}

0 commit comments

Comments
 (0)