flowey_lib_common/
download_cargo_nextest.rs1use crate::cache::CacheHit;
7use flowey::node::prelude::*;
8
9flowey_request! {
10 pub enum Request {
11 Version(String),
13 InstallWithCargo(WriteVar<SideEffect>),
16 InstallStandalone(WriteVar<PathBuf>),
21 }
22}
23
24new_flow_node!(struct Node);
25
26impl FlowNode for Node {
27 type Request = Request;
28
29 fn imports(ctx: &mut ImportCtx<'_>) {
30 ctx.import::<crate::cache::Node>();
31 ctx.import::<crate::cfg_persistent_dir_cargo_install::Node>();
32 ctx.import::<crate::install_rust::Node>();
33 }
34
35 fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
36 let mut version = None;
37 let mut install_with_cargo = Vec::new();
38 let mut install_standalone = Vec::new();
39
40 for req in requests {
41 match req {
42 Request::Version(v) => same_across_all_reqs("Version", &mut version, v)?,
43 Request::InstallWithCargo(v) => install_with_cargo.push(v),
44 Request::InstallStandalone(v) => install_standalone.push(v),
45 }
46 }
47
48 let version = version.ok_or(anyhow::anyhow!("Missing essential request: Version"))?;
49 let install_with_cargo = install_with_cargo;
50 let install_standalone = install_standalone;
51
52 if install_standalone.is_empty() && install_with_cargo.is_empty() {
55 return Ok(());
56 }
57
58 let cargo_nextest_bin = ctx.platform().binary("cargo-nextest");
59
60 let cache_dir = ctx.emit_rust_stepv("create cargo-nextest cache dir", |_| {
61 |_| Ok(std::env::current_dir()?.absolute()?)
62 });
63
64 let cache_key = ReadVar::from_static(format!("cargo-nextest-{version}"));
65 let hitvar = ctx.reqv(|v| {
66 crate::cache::Request {
67 label: "cargo-nextest".into(),
68 dir: cache_dir.clone(),
69 key: cache_key,
70 restore_keys: None, hitvar: v,
72 }
73 });
74
75 let cargo_install_persistent_dir =
78 ctx.reqv(crate::cfg_persistent_dir_cargo_install::Request);
79 let rust_toolchain = ctx.reqv(crate::install_rust::Request::GetRustupToolchain);
80 let cargo_home = ctx.reqv(crate::install_rust::Request::GetCargoHome);
81 let rust_installed = ctx.reqv(crate::install_rust::Request::EnsureInstalled);
82
83 ctx.emit_rust_step("installing cargo-nextest", |ctx| {
84 install_with_cargo.claim(ctx);
85
86 let install_standalone = install_standalone.claim(ctx);
87 let cache_dir = cache_dir.claim(ctx);
88 let hitvar = hitvar.claim(ctx);
89 let cargo_install_persistent_dir = cargo_install_persistent_dir.claim(ctx);
90 let rust_toolchain = rust_toolchain.claim(ctx);
91 let cargo_home = cargo_home.claim(ctx);
92 rust_installed.claim(ctx);
93
94 move |rt| {
95 let cache_dir = rt.read(cache_dir);
96 let cargo_install_persistent_dir = rt.read(cargo_install_persistent_dir);
97 let rust_toolchain = rt.read(rust_toolchain);
98 let cargo_home = rt.read(cargo_home);
99
100 let cached_bin_path = cache_dir.join(&cargo_nextest_bin);
101 let cached = if matches!(rt.read(hitvar), CacheHit::Hit) {
102 assert!(cached_bin_path.exists());
103 Some(cached_bin_path.clone())
104 } else {
105 None
106 };
107
108 let (cargo_home, path_to_cargo_nextest) = if let Some(cached) = cached {
109 (cargo_home, cached)
110 } else {
111 let root = cargo_install_persistent_dir.unwrap_or("./".into());
112
113 let sh = xshell::Shell::new()?;
114 let run = |offline| {
115 let rust_toolchain = rust_toolchain.as_ref();
116 let rust_toolchain = rust_toolchain.map(|s| format!("+{s}"));
117
118 xshell::cmd!(
119 sh,
120 "cargo {rust_toolchain...}
121 install
122 --locked
123 {offline...}
124 --root {root}
125 --target-dir {root}
126 --version {version}
127 cargo-nextest
128 "
129 )
130 .run()
131 };
132
133 if run(Some("--offline")).is_err() {
135 run(None)?;
137 }
138
139 let out_bin = root.absolute()?.join("bin").join(&cargo_nextest_bin);
140
141 fs_err::rename(out_bin, &cached_bin_path)?;
143 let final_bin = cached_bin_path.absolute()?;
144
145 (cargo_home, final_bin)
146 };
147
148 fs_err::copy(
151 &path_to_cargo_nextest,
152 cargo_home.join("bin").join(&cargo_nextest_bin),
153 )?;
154
155 for var in install_standalone {
156 rt.write(var, &path_to_cargo_nextest)
157 }
158
159 Ok(())
160 }
161 });
162
163 Ok(())
164 }
165}