use std::env;
use crate::{
errors::{DistError, DistResult},
DistGraph, SortedMap,
};
use axoprocess::Cmd;
use camino::Utf8Path;
pub fn fetch_brew_env(
dist_graph: &DistGraph,
working_dir: &Utf8Path,
) -> DistResult<Option<Vec<String>>> {
if let Some(brew) = &dist_graph.tools.brew {
if Utf8Path::new("Brewfile").exists() {
let result = Cmd::new(&brew.cmd, "brew bundle exec")
.arg("bundle")
.arg("exec")
.arg("--")
.arg("/usr/bin/env")
.arg("-0")
.current_dir(working_dir)
.output()?;
let s = String::from_utf8_lossy(&result.stdout).to_string();
let output = s
.trim_end()
.trim_end_matches('\0')
.split('\0')
.map(String::from)
.collect();
return Ok(Some(output));
}
}
Ok(None)
}
pub fn parse_env(env: &[String]) -> DistResult<SortedMap<&str, &str>> {
let mut parsed = SortedMap::new();
for line in env {
let Some((key, value)) = line.split_once('=') else {
return Err(DistError::EnvParseError {
line: line.to_owned(),
});
};
parsed.insert(key, value);
}
Ok(parsed)
}
fn formulas_from_env(environment: &SortedMap<&str, &str>) -> Vec<(String, String)> {
let mut packages = vec![];
if let Some(formulastring) = environment.get("HOMEBREW_DEPENDENCIES") {
if let Some(opt_prefix) = environment.get("HOMEBREW_OPT") {
for dep in formulastring.split(',') {
let short_name = dep.split('/').next_back().unwrap();
let pkg_opt = format!("{opt_prefix}/{short_name}");
packages.push((dep.to_owned(), pkg_opt));
}
}
}
packages
}
pub fn select_brew_env(environment: &SortedMap<&str, &str>) -> Vec<(String, String)> {
let mut desired_env = vec![];
if let Some(value) = environment.get("PKG_CONFIG_PATH") {
desired_env.push(("PKG_CONFIG_PATH".to_owned(), value.to_string()))
}
if let Some(value) = environment.get("PKG_CONFIG_LIBDIR") {
desired_env.push(("PKG_CONFIG_LIBDIR".to_owned(), value.to_string()))
}
if let Some(value) = environment.get("CMAKE_INCLUDE_PATH") {
desired_env.push(("CMAKE_INCLUDE_PATH".to_owned(), value.to_string()))
}
if let Some(value) = environment.get("CMAKE_LIBRARY_PATH") {
desired_env.push(("CMAKE_LIBRARY_PATH".to_owned(), value.to_string()))
}
let mut paths = vec![];
for (_, pkg_opt) in formulas_from_env(environment) {
paths.push(format!("{pkg_opt}/bin"));
paths.push(format!("{pkg_opt}/sbin"));
}
if !paths.is_empty() {
if let Ok(our_path) = env::var("PATH") {
let desired_path = format!("{our_path}:{}", paths.join(":"));
desired_env.insert(0, ("PATH".to_owned(), desired_path));
}
}
desired_env
}
pub fn calculate_ldflags(environment: &SortedMap<&str, &str>) -> String {
formulas_from_env(environment)
.iter()
.map(|(_, pkg_opt)| format!("-L{pkg_opt}/lib"))
.collect::<Vec<String>>()
.join(" ")
}
pub fn calculate_cflags(environment: &SortedMap<&str, &str>) -> String {
formulas_from_env(environment)
.iter()
.map(|(_, pkg_opt)| format!("-I{pkg_opt}/include"))
.collect::<Vec<String>>()
.join(" ")
}