pgx_pg_config/
path_methods.rs

1use eyre::{eyre, WrapErr};
2use serde_json::value::Value as JsonValue;
3use std::path::PathBuf;
4use std::process::Command;
5
6// Originally part of `pgx-utils`
7pub fn prefix_path<P: Into<PathBuf>>(dir: P) -> String {
8    let mut path = std::env::split_paths(&std::env::var_os("PATH").expect("failed to get $PATH"))
9        .collect::<Vec<_>>();
10
11    path.insert(0, dir.into());
12    std::env::join_paths(path)
13        .expect("failed to join paths")
14        .into_string()
15        .expect("failed to construct path")
16}
17
18// Originally part of `pgx-utils`
19pub fn get_target_dir() -> eyre::Result<PathBuf> {
20    let cargo = std::env::var_os("CARGO").unwrap_or_else(|| "cargo".into());
21    let mut command = Command::new(cargo);
22    command.arg("metadata").arg("--format-version=1").arg("--no-deps");
23    let output =
24        command.output().wrap_err("Unable to get target directory from `cargo metadata`")?;
25    if !output.status.success() {
26        return Err(eyre!("'cargo metadata' failed with exit code: {}", output.status));
27    }
28
29    let json: JsonValue =
30        serde_json::from_slice(&output.stdout).wrap_err("Invalid `cargo metadata` response")?;
31    let target_dir = json.get("target_directory");
32    match target_dir {
33        Some(JsonValue::String(target_dir)) => Ok(target_dir.into()),
34        v => Err(eyre!("could not read target dir from `cargo metadata` got: {:?}", v,)),
35    }
36}