1use std::env;
2use std::process::Command;
3
4use camino::{Utf8Path, Utf8PathBuf};
5use tracing::*;
6
7use crate::common::Config;
8
9#[cfg(test)]
10mod tests;
11
12pub fn make_new_path(path: &str) -> String {
13 assert!(cfg!(windows));
14 match env::var(lib_path_env_var()) {
17 Ok(curr) => format!("{}{}{}", path, path_div(), curr),
18 Err(..) => path.to_owned(),
19 }
20}
21
22pub fn lib_path_env_var() -> &'static str {
23 "PATH"
24}
25fn path_div() -> &'static str {
26 ";"
27}
28
29pub fn logv(config: &Config, s: String) {
30 debug!("{}", s);
31 if config.verbose {
32 println!("{}", s);
34 }
35}
36
37pub trait Utf8PathBufExt {
38 fn with_extra_extension(&self, extension: &str) -> Utf8PathBuf;
40}
41
42impl Utf8PathBufExt for Utf8PathBuf {
43 fn with_extra_extension(&self, extension: &str) -> Utf8PathBuf {
44 if extension.is_empty() {
45 self.clone()
46 } else {
47 let mut fname = self.file_name().unwrap().to_string();
48 if !extension.starts_with('.') {
49 fname.push_str(".");
50 }
51 fname.push_str(extension);
52 self.with_file_name(fname)
53 }
54 }
55}
56
57pub fn dylib_env_var() -> &'static str {
59 if cfg!(windows) {
60 "PATH"
61 } else if cfg!(target_vendor = "apple") {
62 "DYLD_LIBRARY_PATH"
63 } else if cfg!(target_os = "haiku") {
64 "LIBRARY_PATH"
65 } else if cfg!(target_os = "aix") {
66 "LIBPATH"
67 } else {
68 "LD_LIBRARY_PATH"
69 }
70}
71
72pub fn add_dylib_path(
75 cmd: &mut Command,
76 paths: impl Iterator<Item = impl Into<std::path::PathBuf>>,
77) {
78 let path_env = env::var_os(dylib_env_var());
79 let old_paths = path_env.as_ref().map(env::split_paths);
80 let new_paths = paths.map(Into::into).chain(old_paths.into_iter().flatten());
81 cmd.env(dylib_env_var(), env::join_paths(new_paths).unwrap());
82}
83
84pub fn copy_dir_all(src: &Utf8Path, dst: &Utf8Path) -> std::io::Result<()> {
85 std::fs::create_dir_all(dst.as_std_path())?;
86 for entry in std::fs::read_dir(src.as_std_path())? {
87 let entry = entry?;
88 let path = Utf8PathBuf::try_from(entry.path()).unwrap();
89 let file_name = path.file_name().unwrap();
90 let ty = entry.file_type()?;
91 if ty.is_dir() {
92 copy_dir_all(&path, &dst.join(file_name))?;
93 } else {
94 std::fs::copy(path.as_std_path(), dst.join(file_name).as_std_path())?;
95 }
96 }
97 Ok(())
98}
99
100macro_rules! static_regex {
101 ($re:literal) => {{
102 static RE: ::std::sync::OnceLock<::regex::Regex> = ::std::sync::OnceLock::new();
103 RE.get_or_init(|| ::regex::Regex::new($re).unwrap())
104 }};
105}
106pub(crate) use static_regex;