-
Notifications
You must be signed in to change notification settings - Fork 113
/
Copy pathmain.rs
116 lines (95 loc) · 3.42 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
#[cfg(test)]
mod tidy;
use std::time::Instant;
use xshell::{cmd, Shell};
const MSRV: &str = "1.56.0";
fn main() -> xshell::Result<()> {
let sh = Shell::new()?;
let _e = push_toolchain(&sh, "stable")?;
{
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()?;
}
{
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")?;
cmd!(sh, "cargo build").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))
}