Skip to main content

flowey_lib_common/_util/
cargo_install.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::cache::CacheHit;
5use flowey::node::prelude::*;
6
7pub fn install_cached_cargo_binary(
8    rt: &RustRuntimeServices<'_>,
9    cache_dir: PathBuf,
10    cache_hit: CacheHit,
11    install_root: Option<PathBuf>,
12    rust_toolchain: Option<String>,
13    cargo_home: PathBuf,
14    package: &str,
15    version: &str,
16    binary: &str,
17) -> anyhow::Result<()> {
18    let cached_binary = cache_dir.join(binary);
19
20    let binary_path = if matches!(cache_hit, CacheHit::Hit) {
21        anyhow::ensure!(
22            cached_binary.is_file(),
23            "cache entry for {package} is missing {}",
24            cached_binary.display()
25        );
26        cached_binary
27    } else {
28        let install_root = install_root.unwrap_or_else(|| PathBuf::from("."));
29        let run = |offline| {
30            let rust_toolchain = rust_toolchain.as_ref().map(|s| format!("+{s}"));
31
32            flowey::shell_cmd!(
33                rt,
34                "cargo {rust_toolchain...}
35                    install
36                    --locked
37                    {offline...}
38                    --root {install_root}
39                    --target-dir {install_root}
40                    --version {version}
41                    {package}
42                "
43            )
44            .run()
45        };
46
47        if run(Some("--offline")).is_err() {
48            run(None)?;
49        }
50
51        let installed_binary = install_root.absolute()?.join("bin").join(binary);
52        fs_err::rename(installed_binary, &cached_binary)?;
53        cached_binary.absolute()?
54    };
55
56    fs_err::copy(binary_path, cargo_home.join("bin").join(binary))?;
57
58    Ok(())
59}