1 #[cfg(test)]
2 mod tidy;
3
4 use std::time::Instant;
5
6 use xshell::{cmd, Shell};
7
8 const MSRV: &str = "1.56.0";
9
main() -> xshell::Result<()>10 fn main() -> xshell::Result<()> {
11 let sh = Shell::new()?;
12
13 let _e = push_toolchain(&sh, "stable")?;
14 let _e = sh.push_env("CARGO", "");
15
16 {
17 let _s = section("BUILD");
18 cmd!(sh, "cargo test --workspace --no-run").run()?;
19 }
20
21 {
22 let _s = section("TEST");
23
24 for &release in &[None, Some("--release")] {
25 cmd!(sh, "cargo test --features unstable {release...}").run()?;
26 cmd!(
27 sh,
28 "cargo test --no-default-features --features unstable,std,parking_lot {release...}"
29 )
30 .run()?;
31 }
32
33 // Skip doctests for no_std tests as those don't work
34 cmd!(sh, "cargo test --no-default-features --features unstable --test it").run()?;
35 cmd!(sh, "cargo test --no-default-features --features unstable,alloc --test it").run()?;
36
37 cmd!(sh, "cargo test --no-default-features --features critical-section").run()?;
38 cmd!(sh, "cargo test --features critical-section").run()?;
39 }
40
41 {
42 let _s = section("TEST_BETA");
43 let _e = push_toolchain(&sh, "beta")?;
44 cmd!(sh, "cargo test --features unstable").run()?;
45 }
46
47 {
48 let _s = section("TEST_MSRV");
49 let _e = push_toolchain(&sh, MSRV)?;
50 sh.copy_file("Cargo.lock.msrv", "Cargo.lock")?;
51 cmd!(sh, "cargo build").run()?;
52 }
53
54 {
55 let _s = section("TEST_MIRI");
56 let miri_nightly= cmd!(sh, "curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri").read()?;
57 let _e = push_toolchain(&sh, &format!("nightly-{}", miri_nightly))?;
58
59 sh.remove_path("./target")?;
60
61 cmd!(sh, "rustup component add miri").run()?;
62 cmd!(sh, "cargo miri setup").run()?;
63 cmd!(sh, "cargo miri test --features unstable").run()?;
64 }
65
66 {
67 let _s = section("PUBLISH");
68
69 let version = cmd!(sh, "cargo pkgid").read()?.rsplit_once('#').unwrap().1.to_string();
70 let tag = format!("v{version}");
71
72 let current_branch = cmd!(sh, "git branch --show-current").read()?;
73 let has_tag = cmd!(sh, "git tag --list").read()?.lines().any(|it| it.trim() == tag);
74 let dry_run = sh.var("CI").is_err() || has_tag || current_branch != "master";
75 eprintln!("Publishing{}!", if dry_run { " (dry run)" } else { "" });
76
77 let dry_run_arg = if dry_run { Some("--dry-run") } else { None };
78 cmd!(sh, "cargo publish {dry_run_arg...}").run()?;
79 if dry_run {
80 eprintln!("{}", cmd!(sh, "git tag {tag}"));
81 eprintln!("{}", cmd!(sh, "git push --tags"));
82 } else {
83 cmd!(sh, "git tag {tag}").run()?;
84 cmd!(sh, "git push --tags").run()?;
85 }
86 }
87 Ok(())
88 }
89
push_toolchain<'a>( sh: &'a xshell::Shell, toolchain: &str, ) -> xshell::Result<xshell::PushEnv<'a>>90 fn push_toolchain<'a>(
91 sh: &'a xshell::Shell,
92 toolchain: &str,
93 ) -> xshell::Result<xshell::PushEnv<'a>> {
94 cmd!(sh, "rustup toolchain install {toolchain} --no-self-update").run()?;
95 let res = sh.push_env("RUSTUP_TOOLCHAIN", toolchain);
96 cmd!(sh, "rustc --version").run()?;
97 Ok(res)
98 }
99
section(name: &'static str) -> impl Drop100 fn section(name: &'static str) -> impl Drop {
101 println!("::group::{name}");
102 let start = Instant::now();
103 defer(move || {
104 let elapsed = start.elapsed();
105 eprintln!("{name}: {elapsed:.2?}");
106 println!("::endgroup::");
107 })
108 }
109
defer<F: FnOnce()>(f: F) -> impl Drop110 fn defer<F: FnOnce()>(f: F) -> impl Drop {
111 struct D<F: FnOnce()>(Option<F>);
112 impl<F: FnOnce()> Drop for D<F> {
113 fn drop(&mut self) {
114 if let Some(f) = self.0.take() {
115 f()
116 }
117 }
118 }
119 D(Some(f))
120 }
121