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);
33 }
34}
35
36pub trait Utf8PathBufExt {
37 fn with_extra_extension(&self, extension: &str) -> Utf8PathBuf;
39}
40
41impl Utf8PathBufExt for Utf8PathBuf {
42 fn with_extra_extension(&self, extension: &str) -> Utf8PathBuf {
43 if extension.is_empty() {
44 self.clone()
45 } else {
46 let mut fname = self.file_name().unwrap().to_string();
47 if !extension.starts_with('.') {
48 fname.push_str(".");
49 }
50 fname.push_str(extension);
51 self.with_file_name(fname)
52 }
53 }
54}
55
56pub fn dylib_env_var() -> &'static str {
58 if cfg!(windows) {
59 "PATH"
60 } else if cfg!(target_vendor = "apple") {
61 "DYLD_LIBRARY_PATH"
62 } else if cfg!(target_os = "haiku") {
63 "LIBRARY_PATH"
64 } else if cfg!(target_os = "aix") {
65 "LIBPATH"
66 } else {
67 "LD_LIBRARY_PATH"
68 }
69}
70
71pub fn add_dylib_path(
74 cmd: &mut Command,
75 paths: impl Iterator<Item = impl Into<std::path::PathBuf>>,
76) {
77 let path_env = env::var_os(dylib_env_var());
78 let old_paths = path_env.as_ref().map(env::split_paths);
79 let new_paths = paths.map(Into::into).chain(old_paths.into_iter().flatten());
80 cmd.env(dylib_env_var(), env::join_paths(new_paths).unwrap());
81}
82
83pub fn copy_dir_all(src: &Utf8Path, dst: &Utf8Path) -> std::io::Result<()> {
84 std::fs::create_dir_all(dst.as_std_path())?;
85 for entry in std::fs::read_dir(src.as_std_path())? {
86 let entry = entry?;
87 let path = Utf8PathBuf::try_from(entry.path()).unwrap();
88 let file_name = path.file_name().unwrap();
89 let ty = entry.file_type()?;
90 if ty.is_dir() {
91 copy_dir_all(&path, &dst.join(file_name))?;
92 } else {
93 std::fs::copy(path.as_std_path(), dst.join(file_name).as_std_path())?;
94 }
95 }
96 Ok(())
97}
98
99macro_rules! static_regex {
100 ($re:literal) => {{
101 static RE: ::std::sync::OnceLock<::regex::Regex> = ::std::sync::OnceLock::new();
102 RE.get_or_init(|| ::regex::Regex::new($re).unwrap())
103 }};
104}
105pub(crate) use static_regex;