flux_bin/
utils.rs

1use std::{
2    env,
3    ffi::OsString,
4    fs,
5    path::{Path, PathBuf},
6};
7
8use anyhow::{Result, anyhow};
9use serde::Deserialize;
10
11#[cfg(target_os = "windows")]
12pub const LIB_PATH: &str = "PATH";
13#[cfg(any(target_os = "linux", target_os = "freebsd"))]
14pub const LIB_PATH: &str = "LD_LIBRARY_PATH";
15#[cfg(target_os = "macos")]
16pub const LIB_PATH: &str = "DYLD_FALLBACK_LIBRARY_PATH";
17
18pub const EXIT_ERR: i32 = -1;
19
20pub const FLUX_SYSROOT: &str = "FLUX_SYSROOT";
21
22const FLUX_DRIVER: &str = "FLUX_DRIVER";
23
24/// The path of the flux sysroot lib containing precompiled libraries and the flux driver.
25pub fn sysroot_dir() -> PathBuf {
26    env::var_os(FLUX_SYSROOT).map_or_else(default_sysroot_dir, PathBuf::from)
27}
28
29#[derive(Deserialize)]
30pub struct ToolchainToml {
31    toolchain: ToolchainSpec,
32}
33
34#[derive(Deserialize)]
35pub struct ToolchainSpec {
36    channel: String,
37}
38
39/// Return the default sysroot
40fn default_sysroot_dir() -> PathBuf {
41    home::home_dir()
42        .expect("Couldn't find home directory")
43        .join(".flux")
44}
45
46pub fn get_flux_driver_path(sysroot: &Path) -> Result<PathBuf> {
47    let path = if let Some(path) = env::var_os(FLUX_DRIVER) {
48        PathBuf::from(path)
49    } else {
50        let mut path = sysroot.join("flux-driver");
51        if cfg!(target_os = "windows") {
52            path.set_extension("exe");
53        }
54        path
55    };
56    if !path.is_file() {
57        return Err(anyhow!("path to flux-driver {:?} does not exist or is not a file", path));
58    }
59    Ok(path)
60}
61
62pub fn get_rust_toolchain() -> Result<String> {
63    let toolchain_str = include_str!("../../../rust-toolchain");
64    let toolchain_file: ToolchainToml = toml::from_str(toolchain_str)?;
65    Ok(toolchain_file.toolchain.channel)
66}
67
68/// Path from where to load the rustc-driver library from
69pub fn get_rustc_driver_lib_path(rust_toolchain: &str) -> Result<PathBuf> {
70    let toolchains_path = home::rustup_home()?.join("toolchains");
71    if toolchains_path.is_dir() {
72        let entries = fs::read_dir(toolchains_path)?;
73        for entry in entries {
74            let toolchain_entry = entry?;
75            let file_name = toolchain_entry.file_name().into_string().map_err(|name| {
76                anyhow!("Could not convert Rustup toolchain file name: {:?}", name)
77            })?;
78            if file_name.starts_with(rust_toolchain) {
79                return toolchain_entry
80                    .path()
81                    .join("lib")
82                    .canonicalize()
83                    .map_err(anyhow::Error::from);
84            }
85        }
86    }
87    Err(anyhow!("Could not read Rustup toolchains folder"))
88}
89
90/// Prepends the path so that it's the first checked.
91pub fn prepend_path_to_env_var(var_name: &str, new_path: PathBuf) -> Result<OsString> {
92    let mut paths = match env::var(var_name) {
93        Ok(paths) => env::split_paths(&paths).collect(),
94        Err(env::VarError::NotPresent) => vec![],
95        Err(e) => Err(e)?,
96    };
97    paths.insert(0, new_path);
98    env::join_paths(paths).map_err(anyhow::Error::from)
99}