-
Notifications
You must be signed in to change notification settings - Fork 106
/
main.rs
134 lines (112 loc) · 4.35 KB
/
main.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#[cfg(test)]
mod tidy;
use std::time::Instant;
use xshell::{cmd, Shell};
const MSRV: &str = "1.60.0";
fn main() -> xshell::Result<()> {
let sh = Shell::new()?;
let _e = push_toolchain(&sh, "stable")?;
let _e = sh.push_env("CARGO", "");
{
let _s = section("BUILD");
cmd!(sh, "cargo test --workspace --no-run").run()?;
}
{
let _s = section("TEST");
for &release in &[None, Some("--release")] {
cmd!(sh, "cargo test --features unstable {release...}").run()?;
cmd!(
sh,
"cargo test --no-default-features --features unstable,std,parking_lot {release...}"
)
.run()?;
}
// Skip doctests for no_std tests as those don't work
cmd!(sh, "cargo test --no-default-features --features unstable --test it").run()?;
cmd!(sh, "cargo test --no-default-features --features unstable,alloc --test it").run()?;
cmd!(sh, "cargo test --no-default-features --features critical-section").run()?;
cmd!(sh, "cargo test --features critical-section").run()?;
}
{
let _s = section("TEST_BETA");
let _e = push_toolchain(&sh, "beta")?;
cmd!(sh, "cargo test --features unstable").run()?;
}
{
let _s = section("TEST_MSRV");
let _e = push_toolchain(&sh, MSRV)?;
sh.copy_file("Cargo.lock.msrv", "Cargo.lock")?;
if let err @ Err(_) = cmd!(sh, "cargo update -w -v --locked").run() {
// `Cargo.lock.msrv` is out of date! Probably from having bumped our own version number.
println! {"\
Error: `Cargo.lock.msrv` is out of date. \
Please run:\n \
(cp Cargo.lock{{.msrv,}} && cargo +{MSRV} update -w -v && cp Cargo.lock{{.msrv,}})\n\
\n\
Alternatively, `git apply` the `.patch` below:\
"}
cmd!(sh, "cargo update -q -w").quiet().run()?;
sh.copy_file("Cargo.lock", "Cargo.lock.msrv")?;
cmd!(sh, "git --no-pager diff --color=always -- Cargo.lock.msrv").quiet().run()?;
return err;
}
cmd!(sh, "cargo build --locked").run()?;
}
{
let _s = section("TEST_MIRI");
let miri_nightly= cmd!(sh, "curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri").read()?;
let _e = push_toolchain(&sh, &format!("nightly-{}", miri_nightly))?;
sh.remove_path("./target")?;
cmd!(sh, "rustup component add miri").run()?;
cmd!(sh, "cargo miri setup").run()?;
cmd!(sh, "cargo miri test --features unstable").run()?;
}
{
let _s = section("PUBLISH");
let version = cmd!(sh, "cargo pkgid").read()?.rsplit_once('#').unwrap().1.to_string();
let tag = format!("v{version}");
let current_branch = cmd!(sh, "git branch --show-current").read()?;
let has_tag = cmd!(sh, "git tag --list").read()?.lines().any(|it| it.trim() == tag);
let dry_run = sh.var("CI").is_err() || has_tag || current_branch != "master";
eprintln!("Publishing{}!", if dry_run { " (dry run)" } else { "" });
let dry_run_arg = if dry_run { Some("--dry-run") } else { None };
cmd!(sh, "cargo publish {dry_run_arg...}").run()?;
if dry_run {
eprintln!("{}", cmd!(sh, "git tag {tag}"));
eprintln!("{}", cmd!(sh, "git push --tags"));
} else {
cmd!(sh, "git tag {tag}").run()?;
cmd!(sh, "git push --tags").run()?;
}
}
Ok(())
}
fn push_toolchain<'a>(
sh: &'a xshell::Shell,
toolchain: &str,
) -> xshell::Result<xshell::PushEnv<'a>> {
cmd!(sh, "rustup toolchain install {toolchain} --no-self-update").run()?;
let res = sh.push_env("RUSTUP_TOOLCHAIN", toolchain);
cmd!(sh, "rustc --version").run()?;
Ok(res)
}
fn section(name: &'static str) -> impl Drop {
println!("::group::{name}");
let start = Instant::now();
defer(move || {
let elapsed = start.elapsed();
eprintln!("{name}: {elapsed:.2?}");
println!("::endgroup::");
})
}
fn defer<F: FnOnce()>(f: F) -> impl Drop {
struct D<F: FnOnce()>(Option<F>);
impl<F: FnOnce()> Drop for D<F> {
fn drop(&mut self) {
if let Some(f) = self.0.take() {
f()
}
}
}
D(Some(f))
}