• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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