pgrx_pg_config/
path_methods.rs

1//LICENSE Portions Copyright 2019-2021 ZomboDB, LLC.
2//LICENSE
3//LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc.
4//LICENSE
5//LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. <contact@pgcentral.org>
6//LICENSE
7//LICENSE All rights reserved.
8//LICENSE
9//LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file.
10use eyre::{eyre, WrapErr};
11use serde_json::value::Value as JsonValue;
12use std::path::PathBuf;
13use std::process::Command;
14
15// Originally part of `pgrx-utils`
16pub fn prefix_path<P: Into<PathBuf>>(dir: P) -> String {
17    let mut path = std::env::split_paths(&std::env::var_os("PATH").expect("failed to get $PATH"))
18        .collect::<Vec<_>>();
19
20    path.insert(0, dir.into());
21    std::env::join_paths(path)
22        .expect("failed to join paths")
23        .into_string()
24        .expect("failed to construct path")
25}
26
27/// The target dir, or where we think it will be
28pub fn get_target_dir() -> eyre::Result<PathBuf> {
29    if let Some(path) = std::env::var_os("CARGO_TARGET_DIR") {
30        return Ok(path.into());
31    }
32    // if we don't actually have CARGO_TARGET_DIR set, we try to infer it
33    let cargo = std::env::var_os("CARGO").unwrap_or_else(|| "cargo".into());
34    let mut command = Command::new(cargo);
35    command.arg("metadata").arg("--format-version=1").arg("--no-deps");
36    let output =
37        command.output().wrap_err("Unable to get target directory from `cargo metadata`")?;
38    if !output.status.success() {
39        return Err(eyre!("'cargo metadata' failed with exit code: {}", output.status));
40    }
41
42    let json: JsonValue =
43        serde_json::from_slice(&output.stdout).wrap_err("Invalid `cargo metadata` response")?;
44    let target_dir = json.get("target_directory");
45    match target_dir {
46        Some(JsonValue::String(target_dir)) => Ok(target_dir.into()),
47        v => Err(eyre!("could not read target dir from `cargo metadata` got: {v:?}")),
48    }
49}